diff --git a/.gitignore b/.gitignore index b926b02..54d9801 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ app/Config/database.php app/tmp +app/webroot/zaloha.txt diff --git a/lib/Cake/Cache/Cache.php b/lib/Cake/Cache/Cache.php index cb705f6..e9f27be 100644 --- a/lib/Cake/Cache/Cache.php +++ b/lib/Cake/Cache/Cache.php @@ -1,16 +1,17 @@ 'Apc', * 'prefix' => 'my_app_' * )); - * }}} + * ``` * - * This would configure an APC cache engine to the 'shared' alias. You could then read and write - * to that cache alias by using it for the `$config` parameter in the various Cache methods. In - * general all Cache operations are supported by all cache engines. However, Cache::increment() and + * This would configure an APC cache engine to the 'shared' alias. You could then read and write + * to that cache alias by using it for the `$config` parameter in the various Cache methods. In + * general all Cache operations are supported by all cache engines. However, Cache::increment() and * Cache::decrement() are not supported by File caching. * * @package Cake.Cache @@ -50,6 +51,13 @@ class Cache { */ protected static $_config = array(); +/** + * Group to Config mapping + * + * @var array + */ + protected static $_groups = array(); + /** * Whether to reset the settings with the next call to Cache::set(); * @@ -65,7 +73,7 @@ class Cache { protected static $_engines = array(); /** - * Set the cache configuration to use. config() can + * Set the cache configuration to use. config() can * both create new configurations, return the settings for already configured * configurations. * @@ -95,21 +103,21 @@ class Cache { * handy for deleting a complete group from cache. * - `prefix` Prefix appended to all entries. Good for when you need to share a keyspace * with either another cache config or another application. - * - `probability` Probability of hitting a cache gc cleanup. Setting to 0 will disable + * - `probability` Probability of hitting a cache gc cleanup. Setting to 0 will disable * cache::gc from ever being called automatically. * - `servers' Used by memcache. Give the address of the memcached servers to use. - * - `compress` Used by memcache. Enables memcache's compressed format. - * - `serialize` Used by FileCache. Should cache objects be serialized first. - * - `path` Used by FileCache. Path to where cachefiles should be saved. - * - `lock` Used by FileCache. Should files be locked before writing to them? - * - `user` Used by Xcache. Username for XCache - * - `password` Used by Xcache. Password for XCache + * - `compress` Used by memcache. Enables memcache's compressed format. + * - `serialize` Used by FileCache. Should cache objects be serialized first. + * - `path` Used by FileCache. Path to where cachefiles should be saved. + * - `lock` Used by FileCache. Should files be locked before writing to them? + * - `user` Used by Xcache. Username for XCache + * - `password` Used by Xcache/Redis. Password for XCache/Redis * - * @see app/Config/core.php for configuration settings * @param string $name Name of the configuration * @param array $settings Optional associative array of settings passed to the engine - * @return array(engine, settings) on success, false on failure + * @return array array(engine, settings) on success, false on failure * @throws CacheException + * @see app/Config/core.php for configuration settings */ public static function config($name = null, $settings = array()) { if (is_array($name)) { @@ -117,25 +125,33 @@ class Cache { } $current = array(); - if (isset(self::$_config[$name])) { - $current = self::$_config[$name]; + if (isset(static::$_config[$name])) { + $current = static::$_config[$name]; } if (!empty($settings)) { - self::$_config[$name] = array_merge($current, $settings); + static::$_config[$name] = $settings + $current; } - if (empty(self::$_config[$name]['engine'])) { + if (empty(static::$_config[$name]['engine'])) { return false; } - $engine = self::$_config[$name]['engine']; + if (!empty(static::$_config[$name]['groups'])) { + foreach (static::$_config[$name]['groups'] as $group) { + static::$_groups[$group][] = $name; + sort(static::$_groups[$group]); + static::$_groups[$group] = array_unique(static::$_groups[$group]); + } + } - if (!isset(self::$_engines[$name])) { - self::_buildEngine($name); - $settings = self::$_config[$name] = self::settings($name); - } elseif ($settings = self::set(self::$_config[$name], null, $name)) { - self::$_config[$name] = $settings; + $engine = static::$_config[$name]['engine']; + + if (!isset(static::$_engines[$name])) { + static::_buildEngine($name); + $settings = static::$_config[$name] = static::settings($name); + } elseif ($settings = static::set(static::$_config[$name], null, $name)) { + static::$_config[$name] = $settings; } return compact('engine', 'settings'); } @@ -144,30 +160,35 @@ class Cache { * Finds and builds the instance of the required engine class. * * @param string $name Name of the config array that needs an engine instance built - * @return boolean + * @return bool * @throws CacheException */ protected static function _buildEngine($name) { - $config = self::$_config[$name]; + $config = static::$_config[$name]; list($plugin, $class) = pluginSplit($config['engine'], true); $cacheClass = $class . 'Engine'; App::uses($cacheClass, $plugin . 'Cache/Engine'); if (!class_exists($cacheClass)) { - return false; + throw new CacheException(__d('cake_dev', 'Cache engine %s is not available.', $name)); } $cacheClass = $class . 'Engine'; if (!is_subclass_of($cacheClass, 'CacheEngine')) { - throw new CacheException(__d('cake_dev', 'Cache engines must use CacheEngine as a base class.')); + throw new CacheException(__d('cake_dev', 'Cache engines must use %s as a base class.', 'CacheEngine')); } - self::$_engines[$name] = new $cacheClass(); - if (self::$_engines[$name]->init($config)) { - if (self::$_engines[$name]->settings['probability'] && time() % self::$_engines[$name]->settings['probability'] === 0) { - self::$_engines[$name]->gc(); - } - return true; + static::$_engines[$name] = new $cacheClass(); + if (!static::$_engines[$name]->init($config)) { + $msg = __d( + 'cake_dev', + 'Cache engine "%s" is not properly configured. Ensure required extensions are installed, and credentials/permissions are correct', + $name + ); + throw new CacheException($msg); } - return false; + if (static::$_engines[$name]->settings['probability'] && time() % static::$_engines[$name]->settings['probability'] === 0) { + static::$_engines[$name]->gc(); + } + return true; } /** @@ -176,27 +197,27 @@ class Cache { * @return array Array of configured Cache config names. */ public static function configured() { - return array_keys(self::$_config); + return array_keys(static::$_config); } /** - * Drops a cache engine. Deletes the cache configuration information - * If the deleted configuration is the last configuration using an certain engine, + * Drops a cache engine. Deletes the cache configuration information + * If the deleted configuration is the last configuration using a certain engine, * the Engine instance is also unset. * * @param string $name A currently configured cache config you wish to remove. - * @return boolean success of the removal, returns false when the config does not exist. + * @return bool success of the removal, returns false when the config does not exist. */ public static function drop($name) { - if (!isset(self::$_config[$name])) { + if (!isset(static::$_config[$name])) { return false; } - unset(self::$_config[$name], self::$_engines[$name]); + unset(static::$_config[$name], static::$_engines[$name]); return true; } /** - * Temporarily change the settings on a cache config. The settings will persist for the next write + * Temporarily change the settings on a cache config. The settings will persist for the next write * operation (write, decrement, increment, clear). Any reads that are done before the write, will * use the modified settings. If `$settings` is empty, the settings will be reset to the * original configuration. @@ -222,29 +243,29 @@ class Cache { if (is_array($settings) && $value !== null) { $config = $value; } - if (!isset(self::$_config[$config]) || !isset(self::$_engines[$config])) { + if (!isset(static::$_config[$config]) || !isset(static::$_engines[$config])) { return false; } if (!empty($settings)) { - self::$_reset = true; + static::$_reset = true; } - if (self::$_reset === true) { + if (static::$_reset === true) { if (empty($settings)) { - self::$_reset = false; - $settings = self::$_config[$config]; + static::$_reset = false; + $settings = static::$_config[$config]; } else { if (is_string($settings) && $value !== null) { $settings = array($settings => $value); } - $settings = array_merge(self::$_config[$config], $settings); + $settings += static::$_config[$config]; if (isset($settings['duration']) && !is_numeric($settings['duration'])) { $settings['duration'] = strtotime($settings['duration']) - time(); } } - self::$_engines[$config]->settings = $settings; + static::$_engines[$config]->settings = $settings; } - return self::settings($config); + return static::settings($config); } /** @@ -253,17 +274,15 @@ class Cache { * Permanently remove all expired and deleted data * * @param string $config [optional] The config name you wish to have garbage collected. Defaults to 'default' - * @param integer $expires [optional] An expires timestamp. Defaults to NULL - * @return void + * @param int $expires [optional] An expires timestamp. Defaults to NULL + * @return bool */ public static function gc($config = 'default', $expires = null) { - self::$_engines[$config]->gc($expires); + return static::$_engines[$config]->gc($expires); } /** - * Write data for key into cache. Will automatically use the currently - * active cache configuration. To set the currently active configuration use - * Cache::config() + * Write data for key into a cache engine. * * ### Usage: * @@ -278,32 +297,32 @@ class Cache { * @param string $key Identifier for the data * @param mixed $value Data to be cached - anything except a resource * @param string $config Optional string configuration name to write to. Defaults to 'default' - * @return boolean True if the data was successfully cached, false on failure + * @return bool True if the data was successfully cached, false on failure */ public static function write($key, $value, $config = 'default') { - $settings = self::settings($config); + $settings = static::settings($config); if (empty($settings)) { return false; } - if (!self::isInitialized($config)) { + if (!static::isInitialized($config)) { return false; } - $key = self::$_engines[$config]->key($key); + $key = static::$_engines[$config]->key($key); if (!$key || is_resource($value)) { return false; } - $success = self::$_engines[$config]->write($settings['prefix'] . $key, $value, $settings['duration']); - self::set(null, $config); + $success = static::$_engines[$config]->write($settings['prefix'] . $key, $value, $settings['duration']); + static::set(null, $config); if ($success === false && $value !== '') { trigger_error( __d('cake_dev', "%s cache was unable to write '%s' to %s cache", $config, $key, - self::$_engines[$config]->settings['engine'] + static::$_engines[$config]->settings['engine'] ), E_USER_WARNING ); @@ -312,9 +331,7 @@ class Cache { } /** - * Read a key from the cache. Will automatically use the currently - * active cache configuration. To set the currently active configuration use - * Cache::config() + * Read a key from a cache config. * * ### Usage: * @@ -331,46 +348,46 @@ class Cache { * @return mixed The cached data, or false if the data doesn't exist, has expired, or if there was an error fetching it */ public static function read($key, $config = 'default') { - $settings = self::settings($config); + $settings = static::settings($config); if (empty($settings)) { return false; } - if (!self::isInitialized($config)) { + if (!static::isInitialized($config)) { return false; } - $key = self::$_engines[$config]->key($key); + $key = static::$_engines[$config]->key($key); if (!$key) { return false; } - return self::$_engines[$config]->read($settings['prefix'] . $key); + return static::$_engines[$config]->read($settings['prefix'] . $key); } /** * Increment a number under the key and return incremented value. * * @param string $key Identifier for the data - * @param integer $offset How much to add + * @param int $offset How much to add * @param string $config Optional string configuration name. Defaults to 'default' * @return mixed new value, or false if the data doesn't exist, is not integer, * or if there was an error fetching it. */ public static function increment($key, $offset = 1, $config = 'default') { - $settings = self::settings($config); + $settings = static::settings($config); if (empty($settings)) { return false; } - if (!self::isInitialized($config)) { + if (!static::isInitialized($config)) { return false; } - $key = self::$_engines[$config]->key($key); + $key = static::$_engines[$config]->key($key); - if (!$key || !is_integer($offset) || $offset < 0) { + if (!$key || !is_int($offset) || $offset < 0) { return false; } - $success = self::$_engines[$config]->increment($settings['prefix'] . $key, $offset); - self::set(null, $config); + $success = static::$_engines[$config]->increment($settings['prefix'] . $key, $offset); + static::set(null, $config); return $success; } @@ -378,27 +395,27 @@ class Cache { * Decrement a number under the key and return decremented value. * * @param string $key Identifier for the data - * @param integer $offset How much to subtract + * @param int $offset How much to subtract * @param string $config Optional string configuration name. Defaults to 'default' * @return mixed new value, or false if the data doesn't exist, is not integer, * or if there was an error fetching it */ public static function decrement($key, $offset = 1, $config = 'default') { - $settings = self::settings($config); + $settings = static::settings($config); if (empty($settings)) { return false; } - if (!self::isInitialized($config)) { + if (!static::isInitialized($config)) { return false; } - $key = self::$_engines[$config]->key($key); + $key = static::$_engines[$config]->key($key); - if (!$key || !is_integer($offset) || $offset < 0) { + if (!$key || !is_int($offset) || $offset < 0) { return false; } - $success = self::$_engines[$config]->decrement($settings['prefix'] . $key, $offset); - self::set(null, $config); + $success = static::$_engines[$config]->decrement($settings['prefix'] . $key, $offset); + static::set(null, $config); return $success; } @@ -417,40 +434,40 @@ class Cache { * * @param string $key Identifier for the data * @param string $config name of the configuration to use. Defaults to 'default' - * @return boolean True if the value was successfully deleted, false if it didn't exist or couldn't be removed + * @return bool True if the value was successfully deleted, false if it didn't exist or couldn't be removed */ public static function delete($key, $config = 'default') { - $settings = self::settings($config); + $settings = static::settings($config); if (empty($settings)) { return false; } - if (!self::isInitialized($config)) { + if (!static::isInitialized($config)) { return false; } - $key = self::$_engines[$config]->key($key); + $key = static::$_engines[$config]->key($key); if (!$key) { return false; } - $success = self::$_engines[$config]->delete($settings['prefix'] . $key); - self::set(null, $config); + $success = static::$_engines[$config]->delete($settings['prefix'] . $key); + static::set(null, $config); return $success; } /** * Delete all keys from the cache. * - * @param boolean $check if true will check expiration, otherwise delete all + * @param bool $check if true will check expiration, otherwise delete all * @param string $config name of the configuration to use. Defaults to 'default' - * @return boolean True if the cache was successfully cleared, false otherwise + * @return bool True if the cache was successfully cleared, false otherwise */ public static function clear($check = false, $config = 'default') { - if (!self::isInitialized($config)) { + if (!static::isInitialized($config)) { return false; } - $success = self::$_engines[$config]->clear($check); - self::set(null, $config); + $success = static::$_engines[$config]->clear($check); + static::set(null, $config); return $success; } @@ -459,14 +476,14 @@ class Cache { * * @param string $group name of the group to be cleared * @param string $config name of the configuration to use. Defaults to 'default' - * @return boolean True if the cache group was successfully cleared, false otherwise + * @return bool True if the cache group was successfully cleared, false otherwise */ public static function clearGroup($group, $config = 'default') { - if (!self::isInitialized($config)) { + if (!static::isInitialized($config)) { return false; } - $success = self::$_engines[$config]->clearGroup($group); - self::set(null, $config); + $success = static::$_engines[$config]->clearGroup($group); + static::set(null, $config); return $success; } @@ -474,13 +491,13 @@ class Cache { * Check if Cache has initialized a working config for the given name. * * @param string $config name of the configuration to use. Defaults to 'default' - * @return boolean Whether or not the config name has been initialized. + * @return bool Whether or not the config name has been initialized. */ public static function isInitialized($config = 'default') { if (Configure::read('Cache.disable')) { return false; } - return isset(self::$_engines[$config]); + return isset(static::$_engines[$config]); } /** @@ -491,11 +508,126 @@ class Cache { * @see Cache::config() */ public static function settings($name = 'default') { - if (!empty(self::$_engines[$name])) { - return self::$_engines[$name]->settings(); + if (!empty(static::$_engines[$name])) { + return static::$_engines[$name]->settings(); } return array(); } -} +/** + * Retrieve group names to config mapping. + * + * ``` + * Cache::config('daily', array( + * 'duration' => '1 day', 'groups' => array('posts') + * )); + * Cache::config('weekly', array( + * 'duration' => '1 week', 'groups' => array('posts', 'archive') + * )); + * $configs = Cache::groupConfigs('posts'); + * ``` + * + * $config will equal to `array('posts' => array('daily', 'weekly'))` + * + * @param string $group group name or null to retrieve all group mappings + * @return array map of group and all configuration that has the same group + * @throws CacheException + */ + public static function groupConfigs($group = null) { + if ($group === null) { + return static::$_groups; + } + if (isset(static::$_groups[$group])) { + return array($group => static::$_groups[$group]); + } + throw new CacheException(__d('cake_dev', 'Invalid cache group %s', $group)); + } +/** + * Provides the ability to easily do read-through caching. + * + * When called if the $key is not set in $config, the $callable function + * will be invoked. The results will then be stored into the cache config + * at key. + * + * Examples: + * + * Using a Closure to provide data, assume $this is a Model: + * + * ``` + * $model = $this; + * $results = Cache::remember('all_articles', function() use ($model) { + * return $model->find('all'); + * }); + * ``` + * + * @param string $key The cache key to read/store data at. + * @param callable $callable The callable that provides data in the case when + * the cache key is empty. Can be any callable type supported by your PHP. + * @param string $config The cache configuration to use for this operation. + * Defaults to default. + * @return mixed The results of the callable or unserialized results. + */ + public static function remember($key, $callable, $config = 'default') { + $existing = static::read($key, $config); + if ($existing !== false) { + return $existing; + } + $results = call_user_func($callable); + static::write($key, $results, $config); + return $results; + } + +/** + * Write data for key into a cache engine if it doesn't exist already. + * + * ### Usage: + * + * Writing to the active cache config: + * + * `Cache::add('cached_data', $data);` + * + * Writing to a specific cache config: + * + * `Cache::add('cached_data', $data, 'long_term');` + * + * @param string $key Identifier for the data. + * @param mixed $value Data to be cached - anything except a resource. + * @param string $config Optional string configuration name to write to. Defaults to 'default'. + * @return bool True if the data was successfully cached, false on failure. + * Or if the key existed already. + */ + public static function add($key, $value, $config = 'default') { + $settings = self::settings($config); + + if (empty($settings)) { + return false; + } + if (!self::isInitialized($config)) { + return false; + } + $key = self::$_engines[$config]->key($key); + + if (!$key || is_resource($value)) { + return false; + } + + $success = self::$_engines[$config]->add($settings['prefix'] . $key, $value, $settings['duration']); + self::set(null, $config); + return $success; + } + +/** + * Fetch the engine attached to a specific configuration name. + * + * @param string $config Optional string configuration name to get an engine for. Defaults to 'default'. + * @return null|CacheEngine Null if the engine has not been initialized or the engine. + */ + public static function engine($config = 'default') { + if (self::isInitialized($config)) { + return self::$_engines[$config]; + } + + return null; + } +} diff --git a/lib/Cake/Cache/CacheEngine.php b/lib/Cake/Cache/CacheEngine.php index 9daf4d7..6bad9f7 100644 --- a/lib/Cake/Cache/CacheEngine.php +++ b/lib/Cake/Cache/CacheEngine.php @@ -1,16 +1,17 @@ settings + array( @@ -66,7 +67,7 @@ abstract class CacheEngine { * * Permanently remove all expired and deleted data * - * @param integer $expires [optional] An expires timestamp, invalidataing all data before. + * @param int $expires [optional] An expires timestamp, invalidating all data before. * @return void */ public function gc($expires = null) { @@ -77,11 +78,22 @@ abstract class CacheEngine { * * @param string $key Identifier for the data * @param mixed $value Data to be cached - * @param integer $duration How long to cache for. - * @return boolean True if the data was successfully cached, false on failure + * @param int $duration How long to cache for. + * @return bool True if the data was successfully cached, false on failure */ abstract public function write($key, $value, $duration); +/** + * Write value for a key into cache if it doesn't already exist + * + * @param string $key Identifier for the data + * @param mixed $value Data to be cached + * @param int $duration How long to cache for. + * @return bool True if the data was successfully cached, false on failure + */ + public function add($key, $value, $duration) { + } + /** * Read a key from the cache * @@ -94,7 +106,7 @@ abstract class CacheEngine { * Increment a number under the key and return incremented value * * @param string $key Identifier for the data - * @param integer $offset How much to add + * @param int $offset How much to add * @return New incremented value, false otherwise */ abstract public function increment($key, $offset = 1); @@ -103,7 +115,7 @@ abstract class CacheEngine { * Decrement a number under the key and return decremented value * * @param string $key Identifier for the data - * @param integer $offset How much to subtract + * @param int $offset How much to subtract * @return New incremented value, false otherwise */ abstract public function decrement($key, $offset = 1); @@ -112,25 +124,25 @@ abstract class CacheEngine { * Delete a key from the cache * * @param string $key Identifier for the data - * @return boolean True if the value was successfully deleted, false if it didn't exist or couldn't be removed + * @return bool True if the value was successfully deleted, false if it didn't exist or couldn't be removed */ abstract public function delete($key); /** * Delete all keys from the cache * - * @param boolean $check if true will check expiration, otherwise delete all - * @return boolean True if the cache was successfully cleared, false otherwise + * @param bool $check if true will check expiration, otherwise delete all + * @return bool True if the cache was successfully cleared, false otherwise */ abstract public function clear($check); /** - * Clears all values belonging to a group. Is upt to the implementing engine - * to decide whether actually deete the keys or just simulate it to acheive + * Clears all values belonging to a group. Is up to the implementing engine + * to decide whether actually delete the keys or just simulate it to achieve * the same result. * - * @param string $groups name of the group to be cleared - * @return boolean + * @param string $group name of the group to be cleared + * @return bool */ public function clearGroup($group) { return false; @@ -175,5 +187,4 @@ abstract class CacheEngine { $key = preg_replace('/[\s]+/', '_', strtolower(trim(str_replace(array(DS, '/', '.'), '_', strval($key))))); return $prefix . $key; } - } diff --git a/lib/Cake/Cache/Engine/ApcEngine.php b/lib/Cake/Cache/Engine/ApcEngine.php index 7b93cbb..8500560 100644 --- a/lib/Cake/Cache/Engine/ApcEngine.php +++ b/lib/Cake/Cache/Engine/ApcEngine.php @@ -2,20 +2,18 @@ /** * APC storage engine for cache. * - * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package Cake.Cache.Engine * @since CakePHP(tm) v 1.2.0.4933 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ /** @@ -27,12 +25,19 @@ class ApcEngine extends CacheEngine { /** * Contains the compiled group names - * (prefixed witht the global configuration prefix) + * (prefixed with the global configuration prefix) * * @var array - **/ + */ protected $_compiledGroupNames = array(); +/** + * APC or APCu extension + * + * @var string + */ + protected $_apcExtension = 'apc'; + /** * Initialize the Cache Engine * @@ -40,7 +45,7 @@ class ApcEngine extends CacheEngine { * To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array()); * * @param array $settings array of setting for the engine - * @return boolean True if the engine has been successfully initialized, false if not + * @return bool True if the engine has been successfully initialized, false if not * @see CacheEngine::__defaults */ public function init($settings = array()) { @@ -49,6 +54,10 @@ class ApcEngine extends CacheEngine { } $settings += array('engine' => 'Apc'); parent::init($settings); + if (function_exists('apcu_dec')) { + $this->_apcExtension = 'apcu'; + return true; + } return function_exists('apc_dec'); } @@ -57,17 +66,17 @@ class ApcEngine extends CacheEngine { * * @param string $key Identifier for the data * @param mixed $value Data to be cached - * @param integer $duration How long to cache the data, in seconds - * @return boolean True if the data was successfully cached, false on failure + * @param int $duration How long to cache the data, in seconds + * @return bool True if the data was successfully cached, false on failure */ public function write($key, $value, $duration) { - if ($duration == 0) { - $expires = 0; - } else { + $expires = 0; + if ($duration) { $expires = time() + $duration; } - apc_store($key . '_expires', $expires, $duration); - return apc_store($key, $value, $duration); + $func = $this->_apcExtension . '_store'; + $func($key . '_expires', $expires, $duration); + return $func($key, $value, $duration); } /** @@ -78,62 +87,74 @@ class ApcEngine extends CacheEngine { */ public function read($key) { $time = time(); - $cachetime = intval(apc_fetch($key . '_expires')); + $func = $this->_apcExtension . '_fetch'; + $cachetime = (int)$func($key . '_expires'); if ($cachetime !== 0 && ($cachetime < $time || ($time + $this->settings['duration']) < $cachetime)) { return false; } - return apc_fetch($key); + return $func($key); } /** * Increments the value of an integer cached key * * @param string $key Identifier for the data - * @param integer $offset How much to increment + * @param int $offset How much to increment * @return New incremented value, false otherwise */ public function increment($key, $offset = 1) { - return apc_inc($key, $offset); + $func = $this->_apcExtension . '_inc'; + return $func($key, $offset); } /** * Decrements the value of an integer cached key * * @param string $key Identifier for the data - * @param integer $offset How much to subtract + * @param int $offset How much to subtract * @return New decremented value, false otherwise */ public function decrement($key, $offset = 1) { - return apc_dec($key, $offset); + $func = $this->_apcExtension . '_dec'; + return $func($key, $offset); } /** * Delete a key from the cache * * @param string $key Identifier for the data - * @return boolean True if the value was successfully deleted, false if it didn't exist or couldn't be removed + * @return bool True if the value was successfully deleted, false if it didn't exist or couldn't be removed */ public function delete($key) { - return apc_delete($key); + $func = $this->_apcExtension . '_delete'; + return $func($key); } /** - * Delete all keys from the cache. This will clear every cache config using APC. + * Delete all keys from the cache. This will clear every cache config using APC. * - * @param boolean $check If true, nothing will be cleared, as entries are removed - * from APC as they expired. This flag is really only used by FileEngine. - * @return boolean True Returns true. + * @param bool $check If true, nothing will be cleared, as entries are removed + * from APC as they expired. This flag is really only used by FileEngine. + * @return bool True Returns true. */ public function clear($check) { if ($check) { return true; } - $info = apc_cache_info('user'); - $cacheKeys = $info['cache_list']; - unset($info); - foreach ($cacheKeys as $key) { + $func = $this->_apcExtension . '_delete'; + if (class_exists('APCIterator', false)) { + $iterator = new APCIterator( + 'user', + '/^' . preg_quote($this->settings['prefix'], '/') . '/', + APC_ITER_NONE + ); + $func($iterator); + return true; + } + $cache = $this->_apcExtension === 'apc' ? apc_cache_info('user') : apcu_cache_info(); + foreach ($cache['cache_list'] as $key) { if (strpos($key['info'], $this->settings['prefix']) === 0) { - apc_delete($key['info']); + $func($key['info']); } } return true; @@ -145,7 +166,7 @@ class ApcEngine extends CacheEngine { * the group accordingly. * * @return array - **/ + */ public function groups() { if (empty($this->_compiledGroupNames)) { foreach ($this->settings['groups'] as $group) { @@ -153,11 +174,13 @@ class ApcEngine extends CacheEngine { } } - $groups = apc_fetch($this->_compiledGroupNames); + $fetchFunc = $this->_apcExtension . '_fetch'; + $storeFunc = $this->_apcExtension . '_store'; + $groups = $fetchFunc($this->_compiledGroupNames); if (count($groups) !== count($this->settings['groups'])) { foreach ($this->_compiledGroupNames as $group) { if (!isset($groups[$group])) { - apc_store($group, 1); + $storeFunc($group, 1); $groups[$group] = 1; } } @@ -176,11 +199,32 @@ class ApcEngine extends CacheEngine { * Increments the group value to simulate deletion of all keys under a group * old values will remain in storage until they expire. * - * @return boolean success - **/ + * @param string $group The group to clear. + * @return bool success + */ public function clearGroup($group) { - apc_inc($this->settings['prefix'] . $group, 1, $success); + $func = $this->_apcExtension . '_inc'; + $func($this->settings['prefix'] . $group, 1, $success); return $success; } +/** + * Write data for key into cache if it doesn't exist already. + * If it already exists, it fails and returns false. + * + * @param string $key Identifier for the data. + * @param mixed $value Data to be cached. + * @param int $duration How long to cache the data, in seconds. + * @return bool True if the data was successfully cached, false on failure. + * @link http://php.net/manual/en/function.apc-add.php + */ + public function add($key, $value, $duration) { + $expires = 0; + if ($duration) { + $expires = time() + $duration; + } + $func = $this->_apcExtension . '_add'; + $func($key . '_expires', $expires, $duration); + return $func($key, $value, $duration); + } } diff --git a/lib/Cake/Cache/Engine/FileEngine.php b/lib/Cake/Cache/Engine/FileEngine.php index da68c39..5bbbd93 100644 --- a/lib/Cake/Cache/Engine/FileEngine.php +++ b/lib/Cake/Cache/Engine/FileEngine.php @@ -1,28 +1,27 @@ CACHE * - prefix = string prefix for filename, default => cake_ - * - lock = enable file locking on write, default => false + * - lock = enable file locking on write, default => true * - serialize = serialize the data, default => true * * @var array @@ -54,7 +53,7 @@ class FileEngine extends CacheEngine { /** * True unless FileEngine::__active(); fails * - * @var boolean + * @var bool */ protected $_init = true; @@ -65,7 +64,7 @@ class FileEngine extends CacheEngine { * To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array()); * * @param array $settings array of setting for the engine - * @return boolean True if the engine has been successfully initialized, false if not + * @return bool True if the engine has been successfully initialized, false if not */ public function init($settings = array()) { $settings += array( @@ -94,8 +93,8 @@ class FileEngine extends CacheEngine { /** * Garbage collection. Permanently remove all expired and deleted data * - * @param integer $expires [optional] An expires timestamp, invalidataing all data before. - * @return boolean True if garbage collection was successful, false on failure + * @param int $expires [optional] An expires timestamp, invalidating all data before. + * @return bool True if garbage collection was successful, false on failure */ public function gc($expires = null) { return $this->clear(true); @@ -106,11 +105,11 @@ class FileEngine extends CacheEngine { * * @param string $key Identifier for the data * @param mixed $data Data to be cached - * @param integer $duration How long to cache the data, in seconds - * @return boolean True if the data was successfully cached, false on failure + * @param int $duration How long to cache the data, in seconds + * @return bool True if the data was successfully cached, false on failure */ public function write($key, $data, $duration) { - if ($data === '' || !$this->_init) { + if (!$this->_init) { return false; } @@ -133,7 +132,7 @@ class FileEngine extends CacheEngine { } $expires = time() + $duration; - $contents = $expires . $lineBreak . $data . $lineBreak; + $contents = implode(array($expires, $lineBreak, $data, $lineBreak)); if ($this->settings['lock']) { $this->_File->flock(LOCK_EX); @@ -166,7 +165,7 @@ class FileEngine extends CacheEngine { $this->_File->rewind(); $time = time(); - $cachetime = intval($this->_File->current()); + $cachetime = (int)$this->_File->current(); if ($cachetime !== false && ($cachetime < $time || ($time + $this->settings['duration']) < $cachetime)) { if ($this->settings['lock']) { @@ -201,7 +200,7 @@ class FileEngine extends CacheEngine { * Delete a key from the cache * * @param string $key Identifier for the data - * @return boolean True if the value was successfully deleted, false if it didn't exist or couldn't be removed + * @return bool True if the value was successfully deleted, false if it didn't exist or couldn't be removed */ public function delete($key) { if ($this->_setKey($key) === false || !$this->_init) { @@ -209,60 +208,104 @@ class FileEngine extends CacheEngine { } $path = $this->_File->getRealPath(); $this->_File = null; - return unlink($path); + + //@codingStandardsIgnoreStart + return @unlink($path); + //@codingStandardsIgnoreEnd } /** * Delete all values from the cache * - * @param boolean $check Optional - only delete expired cache items - * @return boolean True if the cache was successfully cleared, false otherwise + * @param bool $check Optional - only delete expired cache items + * @return bool True if the cache was successfully cleared, false otherwise */ public function clear($check) { if (!$this->_init) { return false; } - $dir = dir($this->settings['path']); + $this->_File = null; + + $threshold = $now = false; if ($check) { $now = time(); $threshold = $now - $this->settings['duration']; } + + $this->_clearDirectory($this->settings['path'], $now, $threshold); + + $directory = new RecursiveDirectoryIterator($this->settings['path']); + $contents = new RecursiveIteratorIterator($directory, RecursiveIteratorIterator::SELF_FIRST); + $cleared = array(); + foreach ($contents as $path) { + if ($path->isFile()) { + continue; + } + + $path = $path->getRealPath() . DS; + if (!in_array($path, $cleared)) { + $this->_clearDirectory($path, $now, $threshold); + $cleared[] = $path; + } + } + return true; + } + +/** + * Used to clear a directory of matching files. + * + * @param string $path The path to search. + * @param int $now The current timestamp + * @param int $threshold Any file not modified after this value will be deleted. + * @return void + */ + protected function _clearDirectory($path, $now, $threshold) { $prefixLength = strlen($this->settings['prefix']); + + if (!is_dir($path)) { + return; + } + + $dir = dir($path); while (($entry = $dir->read()) !== false) { if (substr($entry, 0, $prefixLength) !== $this->settings['prefix']) { continue; } - if ($this->_setKey($entry) === false) { + + try { + $file = new SplFileObject($path . $entry, 'r'); + } catch (Exception $e) { continue; } - if ($check) { - $mtime = $this->_File->getMTime(); + + if ($threshold) { + $mtime = $file->getMTime(); if ($mtime > $threshold) { continue; } - - $expires = (int)$this->_File->current(); + $expires = (int)$file->current(); if ($expires > $now) { continue; } } - $path = $this->_File->getRealPath(); - $this->_File = null; - if (file_exists($path)) { - unlink($path); + if ($file->isFile()) { + $filePath = $file->getRealPath(); + $file = null; + + //@codingStandardsIgnoreStart + @unlink($filePath); + //@codingStandardsIgnoreEnd } } - $dir->close(); - return true; } /** * Not implemented * - * @param string $key - * @param integer $offset + * @param string $key The key to decrement + * @param int $offset The number to offset * @return void * @throws CacheException */ @@ -273,8 +316,8 @@ class FileEngine extends CacheEngine { /** * Not implemented * - * @param string $key - * @param integer $offset + * @param string $key The key to decrement + * @param int $offset The number to offset * @return void * @throws CacheException */ @@ -287,8 +330,8 @@ class FileEngine extends CacheEngine { * for the cache file the key is referring to. * * @param string $key The key - * @param boolean $createKey Whether the key should be created if it doesn't exists, or not - * @return boolean true if the cache key could be set, false otherwise + * @param bool $createKey Whether the key should be created if it doesn't exists, or not + * @return bool true if the cache key could be set, false otherwise */ protected function _setKey($key, $createKey = false) { $groups = null; @@ -298,7 +341,7 @@ class FileEngine extends CacheEngine { $dir = $this->settings['path'] . $groups; if (!is_dir($dir)) { - mkdir($dir, 0777, true); + mkdir($dir, 0775, true); } $path = new SplFileInfo($dir . $key); @@ -327,10 +370,16 @@ class FileEngine extends CacheEngine { /** * Determine is cache directory is writable * - * @return boolean + * @return bool */ protected function _active() { $dir = new SplFileInfo($this->settings['path']); + if (Configure::read('debug')) { + $path = $dir->getPathname(); + if (!is_dir($path)) { + mkdir($path, 0775, true); + } + } if ($this->_init && !($dir->isDir() && $dir->isWritable())) { $this->_init = false; trigger_error(__d('cake_dev', '%s is not writable', $this->settings['path']), E_USER_WARNING); @@ -350,24 +399,51 @@ class FileEngine extends CacheEngine { return false; } - $key = Inflector::underscore(str_replace(array(DS, '/', '.'), '_', strval($key))); + $key = Inflector::underscore(str_replace(array(DS, '/', '.', '<', '>', '?', ':', '|', '*', '"'), '_', strval($key))); return $key; } /** * Recursively deletes all files under any directory named as $group * - * @return boolean success - **/ + * @param string $group The group to clear. + * @return bool success + */ public function clearGroup($group) { + $this->_File = null; $directoryIterator = new RecursiveDirectoryIterator($this->settings['path']); $contents = new RecursiveIteratorIterator($directoryIterator, RecursiveIteratorIterator::CHILD_FIRST); foreach ($contents as $object) { $containsGroup = strpos($object->getPathName(), DS . $group . DS) !== false; - if ($object->isFile() && $containsGroup) { - unlink($object->getPathName()); + $hasPrefix = true; + if (strlen($this->settings['prefix']) !== 0) { + $hasPrefix = strpos($object->getBaseName(), $this->settings['prefix']) === 0; + } + if ($object->isFile() && $containsGroup && $hasPrefix) { + $path = $object->getPathName(); + $object = null; + //@codingStandardsIgnoreStart + @unlink($path); + //@codingStandardsIgnoreEnd } } return true; } + +/** + * Write data for key into cache if it doesn't exist already. + * If it already exists, it fails and returns false. + * + * @param string $key Identifier for the data. + * @param mixed $value Data to be cached. + * @param int $duration How long to cache the data, in seconds. + * @return bool True if the data was successfully cached, false on failure. + */ + public function add($key, $value, $duration) { + $cachedValue = $this->read($key); + if ($cachedValue === false) { + return $this->write($key, $value, $duration); + } + return false; + } } diff --git a/lib/Cake/Cache/Engine/MemcacheEngine.php b/lib/Cake/Cache/Engine/MemcacheEngine.php index 4729de3..eba2ec4 100644 --- a/lib/Cake/Cache/Engine/MemcacheEngine.php +++ b/lib/Cake/Cache/Engine/MemcacheEngine.php @@ -2,37 +2,36 @@ /** * Memcache storage engine for cache * - * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package Cake.Cache.Engine * @since CakePHP(tm) v 1.2.0.4933 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ /** - * Memcache storage engine for cache. Memcache has some limitations in the amount of - * control you have over expire times far in the future. See MemcacheEngine::write() for + * Memcache storage engine for cache. Memcache has some limitations in the amount of + * control you have over expire times far in the future. See MemcacheEngine::write() for * more information. * - * @package Cake.Cache.Engine + * @package Cake.Cache.Engine + * @deprecated 3.0.0 You should use the Memcached adapter instead. */ class MemcacheEngine extends CacheEngine { /** * Contains the compiled group names - * (prefixed witht the global configuration prefix) + * (prefixed with the global configuration prefix) * * @var array - **/ + */ protected $_compiledGroupNames = array(); /** @@ -60,7 +59,7 @@ class MemcacheEngine extends CacheEngine { * To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array()); * * @param array $settings array of setting for the engine - * @return boolean True if the engine has been successfully initialized, false if not + * @return bool True if the engine has been successfully initialized, false if not */ public function init($settings = array()) { if (!class_exists('Memcache')) { @@ -98,17 +97,17 @@ class MemcacheEngine extends CacheEngine { } /** - * Parses the server address into the host/port. Handles both IPv6 and IPv4 + * Parses the server address into the host/port. Handles both IPv6 and IPv4 * addresses and Unix sockets * * @param string $server The server address string. * @return array Array containing host, port */ protected function _parseServerString($server) { - if ($server[0] == 'u') { + if (strpos($server, 'unix://') === 0) { return array($server, 0); } - if (substr($server, 0, 1) == '[') { + if (substr($server, 0, 1) === '[') { $position = strpos($server, ']:'); if ($position !== false) { $position++; @@ -126,14 +125,14 @@ class MemcacheEngine extends CacheEngine { } /** - * Write data for key into cache. When using memcache as your cache engine + * Write data for key into cache. When using memcache as your cache engine * remember that the Memcache pecl extension does not support cache expiry times greater * than 30 days in the future. Any duration greater than 30 days will be treated as never expiring. * * @param string $key Identifier for the data * @param mixed $value Data to be cached - * @param integer $duration How long to cache the data, in seconds - * @return boolean True if the data was successfully cached, false on failure + * @param int $duration How long to cache the data, in seconds + * @return bool True if the data was successfully cached, false on failure * @see http://php.net/manual/en/memcache.set.php */ public function write($key, $value, $duration) { @@ -157,14 +156,14 @@ class MemcacheEngine extends CacheEngine { * Increments the value of an integer cached key * * @param string $key Identifier for the data - * @param integer $offset How much to increment + * @param int $offset How much to increment * @return New incremented value, false otherwise * @throws CacheException when you try to increment with compress = true */ public function increment($key, $offset = 1) { if ($this->settings['compress']) { throw new CacheException( - __d('cake_dev', 'Method increment() not implemented for compressed cache in %s', __CLASS__) + __d('cake_dev', 'Method %s not implemented for compressed cache in %s', 'increment()', __CLASS__) ); } return $this->_Memcache->increment($key, $offset); @@ -174,14 +173,14 @@ class MemcacheEngine extends CacheEngine { * Decrements the value of an integer cached key * * @param string $key Identifier for the data - * @param integer $offset How much to subtract + * @param int $offset How much to subtract * @return New decremented value, false otherwise * @throws CacheException when you try to decrement with compress = true */ public function decrement($key, $offset = 1) { if ($this->settings['compress']) { throw new CacheException( - __d('cake_dev', 'Method decrement() not implemented for compressed cache in %s', __CLASS__) + __d('cake_dev', 'Method %s not implemented for compressed cache in %s', 'decrement()', __CLASS__) ); } return $this->_Memcache->decrement($key, $offset); @@ -191,7 +190,7 @@ class MemcacheEngine extends CacheEngine { * Delete a key from the cache * * @param string $key Identifier for the data - * @return boolean True if the value was successfully deleted, false if it didn't exist or couldn't be removed + * @return bool True if the value was successfully deleted, false if it didn't exist or couldn't be removed */ public function delete($key) { return $this->_Memcache->delete($key); @@ -200,20 +199,21 @@ class MemcacheEngine extends CacheEngine { /** * Delete all keys from the cache * - * @param boolean $check - * @return boolean True if the cache was successfully cleared, false otherwise + * @param bool $check If true no deletes will occur and instead CakePHP will rely + * on key TTL values. + * @return bool True if the cache was successfully cleared, false otherwise */ public function clear($check) { if ($check) { return true; } - foreach ($this->_Memcache->getExtendedStats('slabs') as $slabs) { + foreach ($this->_Memcache->getExtendedStats('slabs', 0) as $slabs) { foreach (array_keys($slabs) as $slabId) { if (!is_numeric($slabId)) { continue; } - foreach ($this->_Memcache->getExtendedStats('cachedump', $slabId) as $stats) { + foreach ($this->_Memcache->getExtendedStats('cachedump', $slabId, 0) as $stats) { if (!is_array($stats)) { continue; } @@ -232,8 +232,8 @@ class MemcacheEngine extends CacheEngine { * Connects to a server in connection pool * * @param string $host host ip address or name - * @param integer $port Server port - * @return boolean True if memcache server was connected + * @param int $port Server port + * @return bool True if memcache server was connected */ public function connect($host, $port = 11211) { if ($this->_Memcache->getServerStatus($host, $port) === 0) { @@ -251,7 +251,7 @@ class MemcacheEngine extends CacheEngine { * the group accordingly. * * @return array - **/ + */ public function groups() { if (empty($this->_compiledGroupNames)) { foreach ($this->settings['groups'] as $group) { @@ -283,9 +283,30 @@ class MemcacheEngine extends CacheEngine { * Increments the group value to simulate deletion of all keys under a group * old values will remain in storage until they expire. * - * @return boolean success - **/ + * @param string $group The group to clear. + * @return bool success + */ public function clearGroup($group) { return (bool)$this->_Memcache->increment($this->settings['prefix'] . $group); } + +/** + * Write data for key into cache if it doesn't exist already. When using memcached as your cache engine + * remember that the Memcached PECL extension does not support cache expiry times greater + * than 30 days in the future. Any duration greater than 30 days will be treated as never expiring. + * If it already exists, it fails and returns false. + * + * @param string $key Identifier for the data. + * @param mixed $value Data to be cached. + * @param int $duration How long to cache the data, in seconds. + * @return bool True if the data was successfully cached, false on failure. + * @link http://php.net/manual/en/memcache.add.php + */ + public function add($key, $value, $duration) { + if ($duration > 30 * DAY) { + $duration = 0; + } + + return $this->_Memcache->add($key, $value, $this->settings['compress'], $duration); + } } diff --git a/lib/Cake/Cache/Engine/MemcachedEngine.php b/lib/Cake/Cache/Engine/MemcachedEngine.php new file mode 100644 index 0000000..241b982 --- /dev/null +++ b/lib/Cake/Cache/Engine/MemcachedEngine.php @@ -0,0 +1,365 @@ + 127.0.0.1. If an + * array MemcacheEngine will use them as a pool. + * - compress = boolean, default => false + * - persistent = string The name of the persistent connection. All configurations using + * the same persistent value will share a single underlying connection. + * - serialize = string, default => php. The serializer engine used to serialize data. + * Available engines are php, igbinary and json. Beside php, the memcached extension + * must be compiled with the appropriate serializer support. + * - options - Additional options for the memcached client. Should be an array of option => value. + * Use the Memcached::OPT_* constants as keys. + * + * @var array + */ + public $settings = array(); + +/** + * List of available serializer engines + * + * Memcached must be compiled with json and igbinary support to use these engines + * + * @var array + */ + protected $_serializers = array( + 'igbinary' => Memcached::SERIALIZER_IGBINARY, + 'json' => Memcached::SERIALIZER_JSON, + 'php' => Memcached::SERIALIZER_PHP + ); + +/** + * Initialize the Cache Engine + * + * Called automatically by the cache frontend + * To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array()); + * + * @param array $settings array of setting for the engine + * @return bool True if the engine has been successfully initialized, false if not + * @throws CacheException when you try use authentication without Memcached compiled with SASL support + */ + public function init($settings = array()) { + if (!class_exists('Memcached')) { + return false; + } + if (!isset($settings['prefix'])) { + $settings['prefix'] = Inflector::slug(APP_DIR) . '_'; + } + + if (defined('Memcached::HAVE_MSGPACK') && Memcached::HAVE_MSGPACK) { + $this->_serializers['msgpack'] = Memcached::SERIALIZER_MSGPACK; + } + + $settings += array( + 'engine' => 'Memcached', + 'servers' => array('127.0.0.1'), + 'compress' => false, + 'persistent' => false, + 'login' => null, + 'password' => null, + 'serialize' => 'php', + 'options' => array() + ); + parent::init($settings); + + if (!is_array($this->settings['servers'])) { + $this->settings['servers'] = array($this->settings['servers']); + } + + if (isset($this->_Memcached)) { + return true; + } + + if (!$this->settings['persistent']) { + $this->_Memcached = new Memcached(); + } else { + $this->_Memcached = new Memcached((string)$this->settings['persistent']); + } + $this->_setOptions(); + + if (count($this->_Memcached->getServerList())) { + return true; + } + + $servers = array(); + foreach ($this->settings['servers'] as $server) { + $servers[] = $this->_parseServerString($server); + } + + if (!$this->_Memcached->addServers($servers)) { + return false; + } + + if ($this->settings['login'] !== null && $this->settings['password'] !== null) { + if (!method_exists($this->_Memcached, 'setSaslAuthData')) { + throw new CacheException( + __d('cake_dev', 'Memcached extension is not build with SASL support') + ); + } + $this->_Memcached->setOption(Memcached::OPT_BINARY_PROTOCOL, true); + $this->_Memcached->setSaslAuthData($this->settings['login'], $this->settings['password']); + } + if (is_array($this->settings['options'])) { + foreach ($this->settings['options'] as $opt => $value) { + $this->_Memcached->setOption($opt, $value); + } + } + + return true; + } + +/** + * Settings the memcached instance + * + * @throws CacheException when the Memcached extension is not built with the desired serializer engine + * @return void + */ + protected function _setOptions() { + $this->_Memcached->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true); + + $serializer = strtolower($this->settings['serialize']); + if (!isset($this->_serializers[$serializer])) { + throw new CacheException( + __d('cake_dev', '%s is not a valid serializer engine for Memcached', $serializer) + ); + } + + if ($serializer !== 'php' && !constant('Memcached::HAVE_' . strtoupper($serializer))) { + throw new CacheException( + __d('cake_dev', 'Memcached extension is not compiled with %s support', $serializer) + ); + } + + $this->_Memcached->setOption(Memcached::OPT_SERIALIZER, $this->_serializers[$serializer]); + + // Check for Amazon ElastiCache instance + if (defined('Memcached::OPT_CLIENT_MODE') && defined('Memcached::DYNAMIC_CLIENT_MODE')) { + $this->_Memcached->setOption(Memcached::OPT_CLIENT_MODE, Memcached::DYNAMIC_CLIENT_MODE); + } + + $this->_Memcached->setOption(Memcached::OPT_COMPRESSION, (bool)$this->settings['compress']); + } + +/** + * Parses the server address into the host/port. Handles both IPv6 and IPv4 + * addresses and Unix sockets + * + * @param string $server The server address string. + * @return array Array containing host, port + */ + protected function _parseServerString($server) { + $socketTransport = 'unix://'; + if (strpos($server, $socketTransport) === 0) { + return array(substr($server, strlen($socketTransport)), 0); + } + if (substr($server, 0, 1) === '[') { + $position = strpos($server, ']:'); + if ($position !== false) { + $position++; + } + } else { + $position = strpos($server, ':'); + } + $port = 11211; + $host = $server; + if ($position !== false) { + $host = substr($server, 0, $position); + $port = substr($server, $position + 1); + } + return array($host, (int)$port); + } + +/** + * Write data for key into cache. When using memcached as your cache engine + * remember that the Memcached PECL extension does not support cache expiry times greater + * than 30 days in the future. Any duration greater than 30 days will be treated as never expiring. + * + * @param string $key Identifier for the data + * @param mixed $value Data to be cached + * @param int $duration How long to cache the data, in seconds + * @return bool True if the data was successfully cached, false on failure + * @see http://php.net/manual/en/memcache.set.php + */ + public function write($key, $value, $duration) { + if ($duration > 30 * DAY) { + $duration = 0; + } + + return $this->_Memcached->set($key, $value, $duration); + } + +/** + * Read a key from the cache + * + * @param string $key Identifier for the data + * @return mixed The cached data, or false if the data doesn't exist, has expired, or if there was an error fetching it + */ + public function read($key) { + return $this->_Memcached->get($key); + } + +/** + * Increments the value of an integer cached key + * + * @param string $key Identifier for the data + * @param int $offset How much to increment + * @return New incremented value, false otherwise + * @throws CacheException when you try to increment with compress = true + */ + public function increment($key, $offset = 1) { + return $this->_Memcached->increment($key, $offset); + } + +/** + * Decrements the value of an integer cached key + * + * @param string $key Identifier for the data + * @param int $offset How much to subtract + * @return New decremented value, false otherwise + * @throws CacheException when you try to decrement with compress = true + */ + public function decrement($key, $offset = 1) { + return $this->_Memcached->decrement($key, $offset); + } + +/** + * Delete a key from the cache + * + * @param string $key Identifier for the data + * @return bool True if the value was successfully deleted, false if it didn't exist or couldn't be removed + */ + public function delete($key) { + return $this->_Memcached->delete($key); + } + +/** + * Delete all keys from the cache + * + * @param bool $check If true no deletes will occur and instead CakePHP will rely + * on key TTL values. + * @return bool True if the cache was successfully cleared, false otherwise. Will + * also return false if you are using a binary protocol. + */ + public function clear($check) { + if ($check) { + return true; + } + + $keys = $this->_Memcached->getAllKeys(); + if ($keys === false) { + return false; + } + + foreach ($keys as $key) { + if (strpos($key, $this->settings['prefix']) === 0) { + $this->_Memcached->delete($key); + } + } + + return true; + } + +/** + * Returns the `group value` for each of the configured groups + * If the group initial value was not found, then it initializes + * the group accordingly. + * + * @return array + */ + public function groups() { + if (empty($this->_compiledGroupNames)) { + foreach ($this->settings['groups'] as $group) { + $this->_compiledGroupNames[] = $this->settings['prefix'] . $group; + } + } + + $groups = $this->_Memcached->getMulti($this->_compiledGroupNames); + if (count($groups) !== count($this->settings['groups'])) { + foreach ($this->_compiledGroupNames as $group) { + if (!isset($groups[$group])) { + $this->_Memcached->set($group, 1, 0); + $groups[$group] = 1; + } + } + ksort($groups); + } + + $result = array(); + $groups = array_values($groups); + foreach ($this->settings['groups'] as $i => $group) { + $result[] = $group . $groups[$i]; + } + + return $result; + } + +/** + * Increments the group value to simulate deletion of all keys under a group + * old values will remain in storage until they expire. + * + * @param string $group The group to clear. + * @return bool success + */ + public function clearGroup($group) { + return (bool)$this->_Memcached->increment($this->settings['prefix'] . $group); + } + +/** + * Write data for key into cache if it doesn't exist already. When using memcached as your cache engine + * remember that the Memcached pecl extension does not support cache expiry times greater + * than 30 days in the future. Any duration greater than 30 days will be treated as never expiring. + * If it already exists, it fails and returns false. + * + * @param string $key Identifier for the data. + * @param mixed $value Data to be cached. + * @param int $duration How long to cache the data, in seconds. + * @return bool True if the data was successfully cached, false on failure. + * @link http://php.net/manual/en/memcached.add.php + */ + public function add($key, $value, $duration) { + if ($duration > 30 * DAY) { + $duration = 0; + } + + return $this->_Memcached->add($key, $value, $duration); + } +} diff --git a/lib/Cake/Cache/Engine/RedisEngine.php b/lib/Cake/Cache/Engine/RedisEngine.php index e058dcb..00c8426 100644 --- a/lib/Cake/Cache/Engine/RedisEngine.php +++ b/lib/Cake/Cache/Engine/RedisEngine.php @@ -2,20 +2,18 @@ /** * Redis storage engine for cache * - * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package Cake.Cache.Engine * @since CakePHP(tm) v 2.2 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ /** @@ -35,10 +33,12 @@ class RedisEngine extends CacheEngine { /** * Settings * - * - server = string url or ip to the Redis server host + * - server = string URL or ip to the Redis server host + * - database = integer database number to use for connection * - port = integer port number to the Redis server (default: 6379) * - timeout = float timeout in seconds (default: 0) - * - persistent = bool Connects to the Redis server with a persistent connection (default: true) + * - persistent = boolean Connects to the Redis server with a persistent connection (default: true) + * - unix_socket = path to the unix socket file (default: false) * * @var array */ @@ -51,7 +51,7 @@ class RedisEngine extends CacheEngine { * To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array()); * * @param array $settings array of setting for the engine - * @return boolean True if the engine has been successfully initialized, false if not + * @return bool True if the engine has been successfully initialized, false if not */ public function init($settings = array()) { if (!class_exists('Redis')) { @@ -59,11 +59,14 @@ class RedisEngine extends CacheEngine { } parent::init(array_merge(array( 'engine' => 'Redis', - 'prefix' => null, + 'prefix' => Inflector::slug(APP_DIR) . '_', 'server' => '127.0.0.1', + 'database' => 0, 'port' => 6379, + 'password' => false, 'timeout' => 0, - 'persistent' => true + 'persistent' => true, + 'unix_socket' => false ), $settings) ); @@ -73,21 +76,29 @@ class RedisEngine extends CacheEngine { /** * Connects to a Redis server * - * @return boolean True if Redis server was connected + * @return bool True if Redis server was connected */ protected function _connect() { - $return = false; try { $this->_Redis = new Redis(); - if (empty($this->settings['persistent'])) { + if (!empty($this->settings['unix_socket'])) { + $return = $this->_Redis->connect($this->settings['unix_socket']); + } elseif (empty($this->settings['persistent'])) { $return = $this->_Redis->connect($this->settings['server'], $this->settings['port'], $this->settings['timeout']); } else { - $return = $this->_Redis->pconnect($this->settings['server'], $this->settings['port'], $this->settings['timeout']); + $persistentId = $this->settings['port'] . $this->settings['timeout'] . $this->settings['database']; + $return = $this->_Redis->pconnect($this->settings['server'], $this->settings['port'], $this->settings['timeout'], $persistentId); } } catch (RedisException $e) { + $return = false; + } + if (!$return) { return false; } - return $return; + if ($this->settings['password'] && !$this->_Redis->auth($this->settings['password'])) { + return false; + } + return $this->_Redis->select($this->settings['database']); } /** @@ -95,13 +106,18 @@ class RedisEngine extends CacheEngine { * * @param string $key Identifier for the data * @param mixed $value Data to be cached - * @param integer $duration How long to cache the data, in seconds - * @return boolean True if the data was successfully cached, false on failure + * @param int $duration How long to cache the data, in seconds + * @return bool True if the data was successfully cached, false on failure */ public function write($key, $value, $duration) { if (!is_int($value)) { $value = serialize($value); } + + if (!$this->_Redis->isConnected()) { + $this->_connect(); + } + if ($duration === 0) { return $this->_Redis->set($key, $value); } @@ -117,11 +133,11 @@ class RedisEngine extends CacheEngine { */ public function read($key) { $value = $this->_Redis->get($key); - if (ctype_digit($value)) { - $value = (int)$value; + if (preg_match('/^[-]?\d+$/', $value)) { + return (int)$value; } if ($value !== false && is_string($value)) { - $value = unserialize($value); + return unserialize($value); } return $value; } @@ -130,7 +146,7 @@ class RedisEngine extends CacheEngine { * Increments the value of an integer cached key * * @param string $key Identifier for the data - * @param integer $offset How much to increment + * @param int $offset How much to increment * @return New incremented value, false otherwise * @throws CacheException when you try to increment with compress = true */ @@ -142,7 +158,7 @@ class RedisEngine extends CacheEngine { * Decrements the value of an integer cached key * * @param string $key Identifier for the data - * @param integer $offset How much to subtract + * @param int $offset How much to subtract * @return New decremented value, false otherwise * @throws CacheException when you try to decrement with compress = true */ @@ -154,7 +170,7 @@ class RedisEngine extends CacheEngine { * Delete a key from the cache * * @param string $key Identifier for the data - * @return boolean True if the value was successfully deleted, false if it didn't exist or couldn't be removed + * @return bool True if the value was successfully deleted, false if it didn't exist or couldn't be removed */ public function delete($key) { return $this->_Redis->delete($key) > 0; @@ -163,8 +179,9 @@ class RedisEngine extends CacheEngine { /** * Delete all keys from the cache * - * @param boolean $check - * @return boolean True if the cache was successfully cleared, false otherwise + * @param bool $check Whether or not expiration keys should be checked. If + * true, no keys will be removed as cache will rely on redis TTL's. + * @return bool True if the cache was successfully cleared, false otherwise */ public function clear($check) { if ($check) { @@ -182,7 +199,7 @@ class RedisEngine extends CacheEngine { * the group accordingly. * * @return array - **/ + */ public function groups() { $result = array(); foreach ($this->settings['groups'] as $group) { @@ -200,20 +217,42 @@ class RedisEngine extends CacheEngine { * Increments the group value to simulate deletion of all keys under a group * old values will remain in storage until they expire. * - * @return boolean success - **/ + * @param string $group The group name to clear. + * @return bool success + */ public function clearGroup($group) { return (bool)$this->_Redis->incr($this->settings['prefix'] . $group); } /** * Disconnects from the redis server - * - * @return voind - **/ + */ public function __destruct() { if (!$this->settings['persistent']) { $this->_Redis->close(); } } + +/** + * Write data for key into cache if it doesn't exist already. + * If it already exists, it fails and returns false. + * + * @param string $key Identifier for the data. + * @param mixed $value Data to be cached. + * @param int $duration How long to cache the data, in seconds. + * @return bool True if the data was successfully cached, false on failure. + * @link https://github.com/phpredis/phpredis#setnx + */ + public function add($key, $value, $duration) { + if (!is_int($value)) { + $value = serialize($value); + } + + $result = $this->_Redis->setnx($key, $value); + // setnx() doesn't have an expiry option, so overwrite the key with one + if ($result) { + return $this->_Redis->setex($key, $duration, $value); + } + return false; + } } diff --git a/lib/Cake/Cache/Engine/WincacheEngine.php b/lib/Cake/Cache/Engine/WincacheEngine.php index 8e81312..e5c9d7b 100644 --- a/lib/Cake/Cache/Engine/WincacheEngine.php +++ b/lib/Cake/Cache/Engine/WincacheEngine.php @@ -4,19 +4,18 @@ * * Supports wincache 1.1.0 and higher. * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package Cake.Cache.Engine * @since CakePHP(tm) v 1.2.0.4933 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ /** @@ -28,10 +27,10 @@ class WincacheEngine extends CacheEngine { /** * Contains the compiled group names - * (prefixed witht the global configuration prefix) + * (prefixed with the global configuration prefix) * * @var array - **/ + */ protected $_compiledGroupNames = array(); /** @@ -41,7 +40,7 @@ class WincacheEngine extends CacheEngine { * To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array()); * * @param array $settings array of setting for the engine - * @return boolean True if the engine has been successfully initialized, false if not + * @return bool True if the engine has been successfully initialized, false if not * @see CacheEngine::__defaults */ public function init($settings = array()) { @@ -58,8 +57,8 @@ class WincacheEngine extends CacheEngine { * * @param string $key Identifier for the data * @param mixed $value Data to be cached - * @param integer $duration How long to cache the data, in seconds - * @return boolean True if the data was successfully cached, false on failure + * @param int $duration How long to cache the data, in seconds + * @return bool True if the data was successfully cached, false on failure */ public function write($key, $value, $duration) { $expires = time() + $duration; @@ -81,7 +80,7 @@ class WincacheEngine extends CacheEngine { */ public function read($key) { $time = time(); - $cachetime = intval(wincache_ucache_get($key . '_expires')); + $cachetime = (int)wincache_ucache_get($key . '_expires'); if ($cachetime < $time || ($time + $this->settings['duration']) < $cachetime) { return false; } @@ -92,7 +91,7 @@ class WincacheEngine extends CacheEngine { * Increments the value of an integer cached key * * @param string $key Identifier for the data - * @param integer $offset How much to increment + * @param int $offset How much to increment * @return New incremented value, false otherwise */ public function increment($key, $offset = 1) { @@ -103,7 +102,7 @@ class WincacheEngine extends CacheEngine { * Decrements the value of an integer cached key * * @param string $key Identifier for the data - * @param integer $offset How much to subtract + * @param int $offset How much to subtract * @return New decremented value, false otherwise */ public function decrement($key, $offset = 1) { @@ -114,19 +113,19 @@ class WincacheEngine extends CacheEngine { * Delete a key from the cache * * @param string $key Identifier for the data - * @return boolean True if the value was successfully deleted, false if it didn't exist or couldn't be removed + * @return bool True if the value was successfully deleted, false if it didn't exist or couldn't be removed */ public function delete($key) { return wincache_ucache_delete($key); } /** - * Delete all keys from the cache. This will clear every + * Delete all keys from the cache. This will clear every * item in the cache matching the cache config prefix. * - * @param boolean $check If true, nothing will be cleared, as entries will + * @param bool $check If true, nothing will be cleared, as entries will * naturally expire in wincache.. - * @return boolean True Returns true. + * @return bool True Returns true. */ public function clear($check) { if ($check) { @@ -149,7 +148,7 @@ class WincacheEngine extends CacheEngine { * the group accordingly. * * @return array - **/ + */ public function groups() { if (empty($this->_compiledGroupNames)) { foreach ($this->settings['groups'] as $group) { @@ -180,12 +179,29 @@ class WincacheEngine extends CacheEngine { * Increments the group value to simulate deletion of all keys under a group * old values will remain in storage until they expire. * - * @return boolean success - **/ + * @param string $group The group to clear. + * @return bool success + */ public function clearGroup($group) { $success = null; wincache_ucache_inc($this->settings['prefix'] . $group, 1, $success); return $success; } +/** + * Write data for key into cache if it doesn't exist already. + * If it already exists, it fails and returns false. + * + * @param string $key Identifier for the data. + * @param mixed $value Data to be cached. + * @param int $duration How long to cache the data, in seconds. + * @return bool True if the data was successfully cached, false on failure. + */ + public function add($key, $value, $duration) { + $cachedValue = $this->read($key); + if ($cachedValue === false) { + return $this->write($key, $value, $duration); + } + return false; + } } diff --git a/lib/Cake/Cache/Engine/XcacheEngine.php b/lib/Cake/Cache/Engine/XcacheEngine.php index 8f5d229..c46a7b9 100644 --- a/lib/Cake/Cache/Engine/XcacheEngine.php +++ b/lib/Cake/Cache/Engine/XcacheEngine.php @@ -2,19 +2,18 @@ /** * Xcache storage engine for cache. * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package Cake.Cache.Engine * @since CakePHP(tm) v 1.2.0.4947 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ /** @@ -42,10 +41,10 @@ class XcacheEngine extends CacheEngine { * To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array()); * * @param array $settings array of setting for the engine - * @return boolean True if the engine has been successfully initialized, false if not + * @return bool True if the engine has been successfully initialized, false if not */ public function init($settings = array()) { - if (php_sapi_name() !== 'cli') { + if (PHP_SAPI !== 'cli') { parent::init(array_merge(array( 'engine' => 'Xcache', 'prefix' => Inflector::slug(APP_DIR) . '_', @@ -63,8 +62,8 @@ class XcacheEngine extends CacheEngine { * * @param string $key Identifier for the data * @param mixed $value Data to be cached - * @param integer $duration How long to cache the data, in seconds - * @return boolean True if the data was successfully cached, false on failure + * @param int $duration How long to cache the data, in seconds + * @return bool True if the data was successfully cached, false on failure */ public function write($key, $value, $duration) { $expires = time() + $duration; @@ -81,7 +80,7 @@ class XcacheEngine extends CacheEngine { public function read($key) { if (xcache_isset($key)) { $time = time(); - $cachetime = intval(xcache_get($key . '_expires')); + $cachetime = (int)xcache_get($key . '_expires'); if ($cachetime < $time || ($time + $this->settings['duration']) < $cachetime) { return false; } @@ -95,7 +94,7 @@ class XcacheEngine extends CacheEngine { * If the cache key is not an integer it will be treated as 0 * * @param string $key Identifier for the data - * @param integer $offset How much to increment + * @param int $offset How much to increment * @return New incremented value, false otherwise */ public function increment($key, $offset = 1) { @@ -107,7 +106,7 @@ class XcacheEngine extends CacheEngine { * If the cache key is not an integer it will be treated as 0 * * @param string $key Identifier for the data - * @param integer $offset How much to subtract + * @param int $offset How much to subtract * @return New decremented value, false otherwise */ public function decrement($key, $offset = 1) { @@ -118,7 +117,7 @@ class XcacheEngine extends CacheEngine { * Delete a key from the cache * * @param string $key Identifier for the data - * @return boolean True if the value was successfully deleted, false if it didn't exist or couldn't be removed + * @return bool True if the value was successfully deleted, false if it didn't exist or couldn't be removed */ public function delete($key) { return xcache_unset($key); @@ -127,8 +126,9 @@ class XcacheEngine extends CacheEngine { /** * Delete all keys from the cache * - * @param boolean $check - * @return boolean True if the cache was successfully cleared, false otherwise + * @param bool $check If true no deletes will occur and instead CakePHP will rely + * on key TTL values. + * @return bool True if the cache was successfully cleared, false otherwise */ public function clear($check) { $this->_auth(); @@ -146,7 +146,7 @@ class XcacheEngine extends CacheEngine { * the group accordingly. * * @return array - **/ + */ public function groups() { $result = array(); foreach ($this->settings['groups'] as $group) { @@ -164,8 +164,9 @@ class XcacheEngine extends CacheEngine { * Increments the group value to simulate deletion of all keys under a group * old values will remain in storage until they expire. * - * @return boolean success - **/ + * @param string $group The group to clear. + * @return bool success + */ public function clearGroup($group) { return (bool)xcache_inc($this->settings['prefix'] . $group, 1); } @@ -177,7 +178,7 @@ class XcacheEngine extends CacheEngine { * This has to be done because xcache_clear_cache() needs to pass Basic Http Auth * (see xcache.admin configuration settings) * - * @param boolean $reverse Revert changes + * @param bool $reverse Revert changes * @return void */ protected function _auth($reverse = false) { @@ -206,4 +207,21 @@ class XcacheEngine extends CacheEngine { } } } + +/** + * Write data for key into cache if it doesn't exist already. + * If it already exists, it fails and returns false. + * + * @param string $key Identifier for the data. + * @param mixed $value Data to be cached. + * @param int $duration How long to cache the data, in seconds. + * @return bool True if the data was successfully cached, false on failure. + */ + public function add($key, $value, $duration) { + $cachedValue = $this->read($key); + if ($cachedValue === false) { + return $this->write($key, $value, $duration); + } + return false; + } } diff --git a/lib/Cake/Config/cacert.pem b/lib/Cake/Config/cacert.pem new file mode 100644 index 0000000..b4109e4 --- /dev/null +++ b/lib/Cake/Config/cacert.pem @@ -0,0 +1,3916 @@ +## +## Bundle of CA Root Certificates +## +## Certificate data from Mozilla as of: Wed Jan 20 04:12:04 2016 +## +## The Equifax Secure CA was readded as there were replies to the issue +## that updated this certificate bundle. +## +## This is a bundle of X.509 certificates of public Certificate Authorities +## (CA). These were automatically extracted from Mozilla's root certificates +## file (certdata.txt). This file can be found in the mozilla source tree: +## http://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt +## +## It contains the certificates in PEM format and therefore +## can be directly used with curl / libcurl / php_curl, or with +## an Apache+mod_ssl webserver for SSL client authentication. +## Just configure this file as the SSLCACertificateFile. +## +## Conversion done with mk-ca-bundle.pl version 1.25. +## SHA1: 0ab47e2f41518f8d223eab517cb799e5b071231e +## +# +Equifax Secure CA +================= +-----BEGIN CERTIFICATE----- +MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJVUzEQMA4GA1UE +ChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 +MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoT +B0VxdWlmYXgxLTArBgNVBAsTJEVxdWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCB +nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPR +fM6fBeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+AcJkVV5MW +8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kCAwEAAaOCAQkwggEFMHAG +A1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UE +CxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoG +A1UdEAQTMBGBDzIwMTgwODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvS +spXXR9gjIBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQFMAMB +Af8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUAA4GBAFjOKer89961 +zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y7qj/WsjTVbJmcVfewCHrPSqnI0kB +BIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee95 +70+sB3c4 +-----END CERTIFICATE----- + + +GlobalSign Root CA +================== +-----BEGIN CERTIFICATE----- +MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx +GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds +b2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV +BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD +VQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa +DuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc +THAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb +Kk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP +c1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX +gzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF +AAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj +Y1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG +j/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH +hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC +X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== +-----END CERTIFICATE----- + +GlobalSign Root CA - R2 +======================= +-----BEGIN CERTIFICATE----- +MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4GA1UECxMXR2xv +YmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh +bFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT +aWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln +bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6 +ErPLv4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8eoLrvozp +s6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklqtTleiDTsvHgMCJiEbKjN +S7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzdC9XZzPnqJworc5HGnRusyMvo4KD0L5CL +TfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pazq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6C +ygPCm48CAwEAAaOBnDCBmTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQUm+IHV2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5nbG9i +YWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG3lm0mi3f3BmGLjAN +BgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4GsJ0/WwbgcQ3izDJr86iw8bmEbTUsp +9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu +01yiPqFbQfXf5WRDLenVOavSot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG7 +9G+dwfCMNYxdAfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 +TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== +-----END CERTIFICATE----- + +Verisign Class 3 Public Primary Certification Authority - G3 +============================================================ +-----BEGIN CERTIFICATE----- +MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV +UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv +cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy +dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv +cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkg +Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAMu6nFL8eB8aHm8bN3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1 +EUGO+i2tKmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGukxUc +cLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBmCC+Vk7+qRy+oRpfw +EuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJXwzw3sJ2zq/3avL6QaaiMxTJ5Xpj +055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWuimi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA +ERSWwauSCPc/L8my/uRan2Te2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5f +j267Cz3qWhMeDGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC +/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565pF4ErWjfJXir0 +xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGtTxzhT5yvDwyd93gN2PQ1VoDa +t20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ== +-----END CERTIFICATE----- + +Entrust.net Premium 2048 Secure Server CA +========================================= +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChMLRW50cnVzdC5u +ZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBpbmNvcnAuIGJ5IHJlZi4gKGxp +bWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNV +BAMTKkVudHJ1c3QubmV0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQx +NzUwNTFaFw0yOTA3MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3 +d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTEl +MCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5u +ZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEArU1LqRKGsuqjIAcVFmQqK0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOL +Gp18EzoOH1u3Hs/lJBQesYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSr +hRSGlVuXMlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVTXTzW +nLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/HoZdenoVve8AjhUi +VBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH4QIDAQABo0IwQDAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJ +KoZIhvcNAQEFBQADggEBADubj1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPy +T/4xmf3IDExoU8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf +zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5bu/8j72gZyxKT +J1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+bYQLCIt+jerXmCHG8+c8eS9e +nNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/ErfF6adulZkMV8gzURZVE= +-----END CERTIFICATE----- + +Baltimore CyberTrust Root +========================= +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJRTESMBAGA1UE +ChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3li +ZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoXDTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMC +SUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFs +dGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKME +uyKrmD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsB +UnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/C +G9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9 +XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjpr +l3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoI +VDaGezq1BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEB +BQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT929hkTI7gQCvlYpNRh +cL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3WgxjkzSswF07r51XgdIGn9w/xZchMB5 +hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsa +Y71k5h+3zvDyny67G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H +RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp +-----END CERTIFICATE----- + +AddTrust Low-Value Services Root +================================ +-----BEGIN CERTIFICATE----- +MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML +QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRU +cnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMwMTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQsw +CQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBO +ZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ulCDtbKRY6 +54eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6ntGO0/7Gcrjyvd7ZWxbWr +oulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyldI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1 +Zmne3yzxbrww2ywkEtvrNTVokMsAsJchPXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJui +GMx1I4S+6+JNM3GOGvDC+Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8w +HQYDVR0OBBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8EBTAD +AQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBlMQswCQYDVQQGEwJT +RTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEw +HwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxt +ZBsfzQ3duQH6lmM0MkhHma6X7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0Ph +iVYrqW9yTkkz43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY +eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJlpz/+0WatC7xr +mYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOAWiFeIc9TVPC6b4nbqKqVz4vj +ccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk= +-----END CERTIFICATE----- + +AddTrust External Root +====================== +-----BEGIN CERTIFICATE----- +MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEUMBIGA1UEChML +QWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYD +VQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEw +NDgzOFowbzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRU +cnVzdCBFeHRlcm5hbCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0Eg +Um9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvtH7xsD821 ++iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9uMq/NzgtHj6RQa1wVsfw +Tz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzXmk6vBbOmcZSccbNQYArHE504B4YCqOmo +aSYYkKtMsE8jqzpPhNjfzp/haW+710LXa0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy +2xSoRcRdKn23tNbE7qzNE0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv7 +7+ldU9U0WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYDVR0P +BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0Jvf6xCZU7wO94CTL +VBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRk +VHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENB +IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZl +j7DYd7usQWxHYINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 +6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvCNr4TDea9Y355 +e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEXc4g/VhsxOBi0cQ+azcgOno4u +G+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5amnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= +-----END CERTIFICATE----- + +AddTrust Public Services Root +============================= +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJTRTEUMBIGA1UEChML +QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSAwHgYDVQQDExdBZGRU +cnVzdCBQdWJsaWMgQ0EgUm9vdDAeFw0wMDA1MzAxMDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJ +BgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5l +dHdvcmsxIDAeBgNVBAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+A3S72mnTRqX4jsIMEZBRpS9mVEBV6tsfSlbu +nyNu9DnLoblv8n75XYcmYZ4c+OLspoH4IcUkzBEMP9smcnrHAZcHF/nXGCwwfQ56HmIexkvA/X1i +d9NEHif2P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnPdzRGULD4EfL+OHn3Bzn+UZKXC1sIXzSG +Aa2Il+tmzV7R/9x98oTaunet3IAIx6eH1lWfl2royBFkuucZKT8Rs3iQhCBSWxHveNCD9tVIkNAw +HM+A+WD+eeSI8t0A65RF62WUaUC6wNW0uLp9BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0G +A1UdDgQWBBSBPjfYkrAfd59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zCBjgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDELMAkGA1UEBhMCU0Ux +FDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRUcnVzdCBUVFAgTmV0d29yazEgMB4G +A1UEAxMXQWRkVHJ1c3QgUHVibGljIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4 +JNojVhaTdt02KLmuG7jD8WS6IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL ++YPoRNWyQSW/iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbjPGsye/Kf8Lb93/Ao +GEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bYGozH7ZxOmuASu7VqTITh4SINhwBk/ox9 +Yjllpu9CtoAlEmEBqCQTcAARJl/6NVDFSMwGR+gn2HCNX2TmoUQmXiLsks3/QppEIW1cxeMiHV9H +EufOX1362KqxMy3ZdvJOOjMMK7MtkAY= +-----END CERTIFICATE----- + +AddTrust Qualified Certificates Root +==================================== +-----BEGIN CERTIFICATE----- +MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEUMBIGA1UEChML +QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSMwIQYDVQQDExpBZGRU +cnVzdCBRdWFsaWZpZWQgQ0EgUm9vdDAeFw0wMDA1MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcx +CzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQ +IE5ldHdvcmsxIzAhBgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290MIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoekn0e+EV+vhDTbYjx5eLfpMLXsDBwqxBb/4Oxx +64r1EW7tTw2R0hIYLUkVAcKkIhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G87B4pfYOQnrjfxvM0PC3 +KP0q6p6zsLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i2O+tCBGaKZnhqkRFmhJePp1tUvznoD1o +L/BLcHwTOK28FSXx1s6rosAx1i+f4P8UWfyEk9mHfExUE+uf0S0R+Bg6Ot4l2ffTQO2kBhLEO+GR +wVY18BTcZTYJbqukB8c10cIDMzZbdSZtQvESa0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HU +MIHRMB0GA1UdDgQWBBQ5lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6FrpGkwZzELMAkGA1UE +BhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRUcnVzdCBUVFAgTmV0d29y +azEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVhbGlmaWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQAD +ggEBABmrder4i2VhlRO6aQTvhsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxG +GuoYQ992zPlmhpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx95dr6h+sNNVJn0J6X +dgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKFYqa0p9m9N5xotS1WfbC3P6CxB9bpT9ze +RXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9YiQBCYz95OdBEsIJuQRno3eDB +iFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5noxqE= +-----END CERTIFICATE----- + +Entrust Root Certification Authority +==================================== +-----BEGIN CERTIFICATE----- +MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMCVVMxFjAUBgNV +BAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0Lm5ldC9DUFMgaXMgaW5jb3Jw +b3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMWKGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsG +A1UEAxMkRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0 +MloXDTI2MTEyNzIwNTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMu +MTkwNwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSByZWZlcmVu +Y2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNVBAMTJEVudHJ1c3QgUm9v +dCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ALaVtkNC+sZtKm9I35RMOVcF7sN5EUFoNu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYsz +A9u3g3s+IIRe7bJWKKf44LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOww +Cj0Yzfv9KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGIrb68 +j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi94DkZfs0Nw4pgHBN +rziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOBsDCBrTAOBgNVHQ8BAf8EBAMCAQYw +DwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAigA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1 +MzQyWjAfBgNVHSMEGDAWgBRokORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DH +hmak8fdLQ/uEvW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA +A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9tO1KzKtvn1ISM +Y/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6ZuaAGAT/3B+XxFNSRuzFVJ7yVTa +v52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTS +W3iDVuycNsMm4hH2Z0kdkquM++v/eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0 +tHuu2guQOHXvgR1m0vdXcDazv/wor3ElhVsT/h5/WrQ8 +-----END CERTIFICATE----- + +RSA Security 2048 v3 +==================== +-----BEGIN CERTIFICATE----- +MIIDYTCCAkmgAwIBAgIQCgEBAQAAAnwAAAAKAAAAAjANBgkqhkiG9w0BAQUFADA6MRkwFwYDVQQK +ExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0EgU2VjdXJpdHkgMjA0OCBWMzAeFw0wMTAy +MjIyMDM5MjNaFw0yNjAyMjIyMDM5MjNaMDoxGTAXBgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAb +BgNVBAsTFFJTQSBTZWN1cml0eSAyMDQ4IFYzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAt49VcdKA3XtpeafwGFAyPGJn9gqVB93mG/Oe2dJBVGutn3y+Gc37RqtBaB4Y6lXIL5F4iSj7 +Jylg/9+PjDvJSZu1pJTOAeo+tWN7fyb9Gd3AIb2E0S1PRsNO3Ng3OTsor8udGuorryGlwSMiuLgb +WhOHV4PR8CDn6E8jQrAApX2J6elhc5SYcSa8LWrg903w8bYqODGBDSnhAMFRD0xS+ARaqn1y07iH +KrtjEAMqs6FPDVpeRrc9DvV07Jmf+T0kgYim3WBU6JU2PcYJk5qjEoAAVZkZR73QpXzDuvsf9/UP ++Ky5tfQ3mBMY3oVbtwyCO4dvlTlYMNpuAWgXIszACwIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/ +MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQHw1EwpKrpRa41JPr/JCwz0LGdjDAdBgNVHQ4E +FgQUB8NRMKSq6UWuNST6/yQsM9CxnYwwDQYJKoZIhvcNAQEFBQADggEBAF8+hnZuuDU8TjYcHnmY +v/3VEhF5Ug7uMYm83X/50cYVIeiKAVQNOvtUudZj1LGqlk2iQk3UUx+LEN5/Zb5gEydxiKRz44Rj +0aRV4VCT5hsOedBnvEbIvz8XDZXmxpBp3ue0L96VfdASPz0+f00/FGj1EVDVwfSQpQgdMWD/YIwj +VAqv/qFuxdF6Kmh4zx6CCiC0H63lhbJqaHVOrSU3lIW+vaHU6rcMSzyd6BIA8F+sDeGscGNz9395 +nzIlQnQFgCi/vcEkllgVsRch6YlL2weIZ/QVrXA+L02FO8K32/6YaCOJ4XQP3vTFhGMpG8zLB8kA +pKnXwiJPZ9d37CAFYd4= +-----END CERTIFICATE----- + +GeoTrust Global CA +================== +-----BEGIN CERTIFICATE----- +MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVTMRYwFAYDVQQK +Ew1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9iYWwgQ0EwHhcNMDIwNTIxMDQw +MDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j +LjEbMBkGA1UEAxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjo +BbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDviS2Aelet +8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU1XupGc1V3sjs0l44U+Vc +T4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagU +vTLrGAMoUgRx5aszPeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVk +DBF9qn1luMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKInZ57Q +zxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfStQWVYrmm3ok9Nns4 +d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcFPseKUgzbFbS9bZvlxrFUaKnjaZC2 +mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Unhw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6p +XE0zX5IJL4hmXXeXxx12E6nV5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvm +Mw== +-----END CERTIFICATE----- + +GeoTrust Global CA 2 +==================== +-----BEGIN CERTIFICATE----- +MIIDZjCCAk6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN +R2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFsIENBIDIwHhcNMDQwMzA0MDUw +MDAwWhcNMTkwMzA0MDUwMDAwWjBEMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j +LjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFsIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQDvPE1APRDfO1MA4Wf+lGAVPoWI8YkNkMgoI5kF6CsgncbzYEbYwbLVjDHZ3CB5JIG/ +NTL8Y2nbsSpr7iFY8gjpeMtvy/wWUsiRxP89c96xPqfCfWbB9X5SJBri1WeR0IIQ13hLTytCOb1k +LUCgsBDTOEhGiKEMuzozKmKY+wCdE1l/bztyqu6mD4b5BWHqZ38MN5aL5mkWRxHCJ1kDs6ZgwiFA +Vvqgx306E+PsV8ez1q6diYD3Aecs9pYrEw15LNnA5IZ7S4wMcoKK+xfNAGw6EzywhIdLFnopsk/b +HdQL82Y3vdj2V7teJHq4PIu5+pIaGoSe2HSPqht/XvT+RSIhAgMBAAGjYzBhMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFHE4NvICMVNHK266ZUapEBVYIAUJMB8GA1UdIwQYMBaAFHE4NvICMVNH +K266ZUapEBVYIAUJMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAQEAA/e1K6tdEPx7 +srJerJsOflN4WT5CBP51o62sgU7XAotexC3IUnbHLB/8gTKY0UvGkpMzNTEv/NgdRN3ggX+d6Yvh +ZJFiCzkIjKx0nVnZellSlxG5FntvRdOW2TF9AjYPnDtuzywNA0ZF66D0f0hExghAzN4bcLUprbqL +OzRldRtxIR0sFAqwlpW41uryZfspuk/qkZN0abby/+Ea0AzRdoXLiiW9l14sbxWZJue2Kf8i7MkC +x1YAzUm5s2x7UwQa4qjJqhIFI8LO57sEAszAR6LkxCkvW0VXiVHuPOtSCP8HNR6fNWpHSlaY0VqF +H4z1Ir+rzoPz4iIprn2DQKi6bA== +-----END CERTIFICATE----- + +GeoTrust Universal CA +===================== +-----BEGIN CERTIFICATE----- +MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN +R2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVyc2FsIENBMB4XDTA0MDMwNDA1 +MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu +Yy4xHjAcBgNVBAMTFUdlb1RydXN0IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBAKYVVaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9t +JPi8cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTTQjOgNB0e +RXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFhF7em6fgemdtzbvQKoiFs +7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2vc7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d +8Lsrlh/eezJS/R27tQahsiFepdaVaH/wmZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7V +qnJNk22CDtucvc+081xdVHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3Cga +Rr0BHdCXteGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZf9hB +Z3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfReBi9Fi1jUIxaS5BZu +KGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+nhutxx9z3SxPGWX9f5NAEC7S8O08 +ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0 +XG0D08DYj3rWMB8GA1UdIwQYMBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIB +hjANBgkqhkiG9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc +aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fXIwjhmF7DWgh2 +qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzynANXH/KttgCJwpQzgXQQpAvvL +oJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0zuzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsK +xr2EoyNB3tZ3b4XUhRxQ4K5RirqNPnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxF +KyDuSN/n3QmOGKjaQI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2 +DFKWkoRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9ER/frslK +xfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQtDF4JbAiXfKM9fJP/P6EU +p8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/SfuvmbJxPgWp6ZKy7PtXny3YuxadIwVyQD8vI +P/rmMuGNG2+k5o7Y+SlIis5z/iw= +-----END CERTIFICATE----- + +GeoTrust Universal CA 2 +======================= +-----BEGIN CERTIFICATE----- +MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN +R2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwHhcNMDQwMzA0 +MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3Qg +SW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0 +DE81WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUGFF+3Qs17 +j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdqXbboW0W63MOhBW9Wjo8Q +JqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxLse4YuU6W3Nx2/zu+z18DwPw76L5GG//a +QMJS9/7jOvdqdzXQ2o3rXhhqMcceujwbKNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2 +WP0+GfPtDCapkzj4T8FdIgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP +20gaXT73y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRthAAn +ZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgocQIgfksILAAX/8sgC +SqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4Lt1ZrtmhN79UNdxzMk+MBB4zsslG +8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2 ++/CfXGJx7Tz0RzgQKzAfBgNVHSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8E +BAMCAYYwDQYJKoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z +dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQL1EuxBRa3ugZ +4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgrFg5fNuH8KrUwJM/gYwx7WBr+ +mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSoag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpq +A1Ihn0CoZ1Dy81of398j9tx4TuaYT1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpg +Y+RdM4kX2TGq2tbzGDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiP +pm8m1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJVOCiNUW7d +FGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH6aLcr34YEoP9VhdBLtUp +gn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwXQMAJKOSLakhT2+zNVVXxxvjpoixMptEm +X36vWkzaH6byHCx+rgIW0lbQL1dTR+iS +-----END CERTIFICATE----- + +Visa eCommerce Root +=================== +-----BEGIN CERTIFICATE----- +MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBrMQswCQYDVQQG +EwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2Ug +QXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2 +WhcNMjIwNjI0MDAxNjEyWjBrMQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMm +VmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv +bW1lcmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h2mCxlCfL +F9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4ElpF7sDPwsRROEW+1QK8b +RaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdVZqW1LS7YgFmypw23RuwhY/81q6UCzyr0 +TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI +/k4+oKsGGelT84ATB+0tvz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzs +GHxBvfaLdXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEG +MB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUFAAOCAQEAX/FBfXxc +CLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcRzCSs00Rsca4BIGsDoo8Ytyk6feUW +YFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pz +zkWKsKZJ/0x9nXGIxHYdkFsd7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBu +YQa7FkKMcPcw++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt +398znM/jra6O1I7mT1GvFpLgXPYHDw== +-----END CERTIFICATE----- + +Certum Root CA +============== +-----BEGIN CERTIFICATE----- +MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQK +ExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBDQTAeFw0wMjA2MTExMDQ2Mzla +Fw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8u +by4xEjAQBgNVBAMTCUNlcnR1bSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6x +wS7TT3zNJc4YPk/EjG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdL +kKWoePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GIULdtlkIJ +89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapuOb7kky/ZR6By6/qmW6/K +Uz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUgAKpoC6EahQGcxEZjgoi2IrHu/qpGWX7P +NSzVttpd90gzFFS269lvzs2I1qsb2pY7HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkq +hkiG9w0BAQUFAAOCAQEAuI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+ +GXYkHAQaTOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTgxSvg +GrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1qCjqTE5s7FCMTY5w/ +0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5xO/fIR/RpbxXyEV6DHpx8Uq79AtoS +qFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs6GAqm4VKQPNriiTsBhYscw== +-----END CERTIFICATE----- + +Comodo AAA Services root +======================== +-----BEGIN CERTIFICATE----- +MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS +R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg +TGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAw +MFoXDTI4MTIzMTIzNTk1OVowezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hl +c3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNV +BAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQuaBtDFcCLNSS1UY8y2bmhG +C1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe3M/vg4aijJRPn2jymJBGhCfHdr/jzDUs +i14HZGWCwEiwqJH5YZ92IFCokcdmtet4YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszW +Y19zjNoFmag4qMsXeDZRrOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjH +Ypy+g8cmez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQUoBEK +Iz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wewYDVR0f +BHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNl +cy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29tb2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2Vz +LmNybDANBgkqhkiG9w0BAQUFAAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm +7l3sAg9g1o1QGE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz +Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2G9w84FoVxp7Z +8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsil2D4kF501KKaU73yqWjgom7C +12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== +-----END CERTIFICATE----- + +Comodo Secure Services root +=========================== +-----BEGIN CERTIFICATE----- +MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS +R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg +TGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAw +MDAwMFoXDTI4MTIzMTIzNTk1OVowfjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFu +Y2hlc3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAi +BgNVBAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPMcm3ye5drswfxdySRXyWP +9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3SHpR7LZQdqnXXs5jLrLxkU0C8j6ysNstc +rbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rC +oznl2yY4rYsK7hljxxwk3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3V +p6ea5EQz6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNVHQ4E +FgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w +gYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2RvY2EuY29tL1NlY3VyZUNlcnRpZmlj +YXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRwOi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlm +aWNhdGVTZXJ2aWNlcy5jcmwwDQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm +4J4oqF7Tt/Q05qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj +Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtIgKvcnDe4IRRL +DXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJaD61JlfutuC23bkpgHl9j6Pw +pCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDlizeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1H +RR3B7Hzs/Sk= +-----END CERTIFICATE----- + +Comodo Trusted Services root +============================ +-----BEGIN CERTIFICATE----- +MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS +R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg +TGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEw +MDAwMDBaFw0yODEyMzEyMzU5NTlaMH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1h +bmNoZXN0ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUw +IwYDVQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWWfnJSoBVC21ndZHoa0Lh7 +3TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMtTGo87IvDktJTdyR0nAducPy9C1t2ul/y +/9c3S0pgePfw+spwtOpZqqPOSC+pw7ILfhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6 +juljatEPmsbS9Is6FARW1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsS +ivnkBbA7kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0GA1Ud +DgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21vZG9jYS5jb20vVHJ1c3RlZENlcnRp +ZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRodHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENl +cnRpZmljYXRlU2VydmljZXMuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8Ntw +uleGFTQQuS9/HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32 +pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxISjBc/lDb+XbDA +BHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+xqFx7D+gIIxmOom0jtTYsU0l +R+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/AtyjcndBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O +9y5Xt5hwXsjEeLBi +-----END CERTIFICATE----- + +QuoVadis Root CA +================ +-----BEGIN CERTIFICATE----- +MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJCTTEZMBcGA1UE +ChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 +eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAz +MTkxODMzMzNaFw0yMTAzMTcxODMzMzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRp +cyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQD +EyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Ypli4kVEAkOPcahdxYTMuk +J0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2DrOpm2RgbaIr1VxqYuvXtdj182d6UajtL +F8HVj71lODqV0D1VNk7feVcxKh7YWWVJWCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeL +YzcS19Dsw3sgQUSj7cugF+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWen +AScOospUxbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCCAk4w +PQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVvdmFkaXNvZmZzaG9y +ZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREwggENMIIBCQYJKwYBBAG+WAABMIH7 +MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNlIG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmlj +YXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJs +ZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh +Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYIKwYBBQUHAgEW +Fmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3TKbkGGew5Oanwl4Rqy+/fMIGu +BgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rqy+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkw +FwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MS4wLAYDVQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6 +tlCLMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSkfnIYj9lo +fFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf87C9TqnN7Az10buYWnuul +LsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1RcHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2x +gI4JVrmcGmD+XcHXetwReNDWXcG31a0ymQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi +5upZIof4l/UO/erMkqQWxFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi +5nrQNiOKSnQ2+Q== +-----END CERTIFICATE----- + +QuoVadis Root CA 2 +================== +-----BEGIN CERTIFICATE----- +MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT +EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMjAeFw0wNjExMjQx +ODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQCaGMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6 +XJxgFyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55JWpzmM+Yk +lvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bBrrcCaoF6qUWD4gXmuVbB +lDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp+ARz8un+XJiM9XOva7R+zdRcAitMOeGy +lZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt +66/3FsvbzSUr5R/7mp/iUcw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1Jdxn +wQ5hYIizPtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og/zOh +D7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UHoycR7hYQe7xFSkyy +BNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuIyV77zGHcizN300QyNQliBJIWENie +J0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1Ud +DgQWBBQahGK8SEwzJQTU7tD2A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGU +a6FJpEcwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT +ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2fBluornFdLwUv +Z+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzng/iN/Ae42l9NLmeyhP3ZRPx3 +UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2BlfF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodm +VjB3pjd4M1IQWK4/YY7yarHvGH5KWWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK ++JDSV6IZUaUtl0HaB0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrW +IozchLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPRTUIZ3Ph1 +WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWDmbA4CD/pXvk1B+TJYm5X +f6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0ZohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II +4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8 +VCLAAVBpQ570su9t+Oza8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u +-----END CERTIFICATE----- + +QuoVadis Root CA 3 +================== +-----BEGIN CERTIFICATE----- +MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT +EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMzAeFw0wNjExMjQx +OTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQDMV0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNgg +DhoB4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUrH556VOij +KTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd8lyyBTNvijbO0BNO/79K +DDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9CabwvvWhDFlaJKjdhkf2mrk7AyxRllDdLkgbv +BNDInIjbC3uBr7E9KsRlOni27tyAsdLTmZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwp +p5ijJUMv7/FfJuGITfhebtfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8 +nT8KKdjcT5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDtWAEX +MJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZc6tsgLjoC2SToJyM +Gf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A4iLItLRkT9a6fUg+qGkM17uGcclz +uD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYDVR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHT +BgkrBgEEAb5YAAMwgcUwgZMGCCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmlj +YXRlIGNvbnN0aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 +aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVudC4wLQYIKwYB +BQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2NwczALBgNVHQ8EBAMCAQYwHQYD +VR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4GA1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4 +ywLQoUmkRzBFMQswCQYDVQQGEwJCTTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UE +AxMSUXVvVmFkaXMgUm9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZV +qyM07ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSemd1o417+s +hvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd+LJ2w/w4E6oM3kJpK27z +POuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2 +Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadNt54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp +8kokUvd0/bpO5qgdAm6xDYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBC +bjPsMZ57k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6szHXu +g/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0jWy10QJLZYxkNc91p +vGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeTmJlglFwjz1onl14LBQaTNx47aTbr +qZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK4SVhM7JZG+Ju1zdXtg2pEto= +-----END CERTIFICATE----- + +Security Communication Root CA +============================== +-----BEGIN CERTIFICATE----- +MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP +U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw +HhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP +U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw +8yl89f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJDKaVv0uM +DPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9Ms+k2Y7CI9eNqPPYJayX +5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/NQV3Is00qVUarH9oe4kA92819uZKAnDfd +DJZkndwi92SL32HeFZRSFaB9UslLqCHJxrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2 +JChzAgMBAAGjPzA9MB0GA1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYw +DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vGkl3g +0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfrUj94nK9NrvjVT8+a +mCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5Bw+SUEmK3TGXX8npN6o7WWWXlDLJ +s58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJUJRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ +6rBK+1YWc26sTfcioU+tHXotRSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAi +FL39vmwLAw== +-----END CERTIFICATE----- + +Sonera Class 2 Root CA +====================== +-----BEGIN CERTIFICATE----- +MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEPMA0GA1UEChMG +U29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAxMDQwNjA3Mjk0MFoXDTIxMDQw +NjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNVBAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJh +IENsYXNzMiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3 +/Ei9vX+ALTU74W+oZ6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybT +dXnt5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s3TmVToMG +f+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2EjvOr7nQKV0ba5cTppCD8P +tOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu8nYybieDwnPz3BjotJPqdURrBGAgcVeH +nfO+oJAjPYok4doh28MCAwEAAaMzMDEwDwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITT +XjwwCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt +0jSv9zilzqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/3DEI +cbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvDFNr450kkkdAdavph +Oe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6Tk6ezAyNlNzZRZxe7EJQY670XcSx +EtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLH +llpwrN9M +-----END CERTIFICATE----- + +Staat der Nederlanden Root CA +============================= +-----BEGIN CERTIFICATE----- +MIIDujCCAqKgAwIBAgIEAJiWijANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJOTDEeMBwGA1UE +ChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFhdCBkZXIgTmVkZXJsYW5kZW4g +Um9vdCBDQTAeFw0wMjEyMTcwOTIzNDlaFw0xNTEyMTYwOTE1MzhaMFUxCzAJBgNVBAYTAk5MMR4w +HAYDVQQKExVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xJjAkBgNVBAMTHVN0YWF0IGRlciBOZWRlcmxh +bmRlbiBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmNK1URF6gaYUmHFt +vsznExvWJw56s2oYHLZhWtVhCb/ekBPHZ+7d89rFDBKeNVU+LCeIQGv33N0iYfXCxw719tV2U02P +jLwYdjeFnejKScfST5gTCaI+Ioicf9byEGW07l8Y1Rfj+MX94p2i71MOhXeiD+EwR+4A5zN9RGca +C1Hoi6CeUJhoNFIfLm0B8mBF8jHrqTFoKbt6QZ7GGX+UtFE5A3+y3qcym7RHjm+0Sq7lr7HcsBth +vJly3uSJt3omXdozSVtSnA71iq3DuD3oBmrC1SoLbHuEvVYFy4ZlkuxEK7COudxwC0barbxjiDn6 +22r+I/q85Ej0ZytqERAhSQIDAQABo4GRMIGOMAwGA1UdEwQFMAMBAf8wTwYDVR0gBEgwRjBEBgRV +HSAAMDwwOgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cucGtpb3ZlcmhlaWQubmwvcG9saWNpZXMvcm9v +dC1wb2xpY3kwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSofeu8Y6R0E3QA7Jbg0zTBLL9s+DAN +BgkqhkiG9w0BAQUFAAOCAQEABYSHVXQ2YcG70dTGFagTtJ+k/rvuFbQvBgwp8qiSpGEN/KtcCFtR +EytNwiphyPgJWPwtArI5fZlmgb9uXJVFIGzmeafR2Bwp/MIgJ1HI8XxdNGdphREwxgDS1/PTfLbw +MVcoEoJz6TMvplW0C5GUR5z6u3pCMuiufi3IvKwUv9kP2Vv8wfl6leF9fpb8cbDCTMjfRTTJzg3y +nGQI0DvDKcWy7ZAEwbEpkcUwb8GpcjPM/l0WFywRaed+/sWDCN+83CI6LiBpIzlWYGeQiy52OfsR +iJf2fL1LuCAWZwWN4jvBcj+UlTfHXbme2JOhF4//DGYVwSR8MnwDHTuhWEUykw== +-----END CERTIFICATE----- + +UTN USERFirst Hardware Root CA +============================== +-----BEGIN CERTIFICATE----- +MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCBlzELMAkGA1UE +BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl +IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAd +BgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgx +OTIyWjCBlzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0 +eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVz +ZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlI +wrthdBKWHTxqctU8EGc6Oe0rE81m65UJM6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFd +tqdt++BxF2uiiPsA3/4aMXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8 +i4fDidNdoI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqIDsjf +Pe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9KsyoUhbAgMBAAGjgbkw +gbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFKFyXyYbKJhDlV0HN9WF +lp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNF +UkZpcnN0LUhhcmR3YXJlLmNybDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUF +BwMGBggrBgEFBQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM +//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28GpgoiskliCE7/yMgUsogW +XecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gECJChicsZUN/KHAG8HQQZexB2 +lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kn +iCrVWFCVH/A7HFe7fRQ5YiuayZSSKqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67 +nfhmqA== +-----END CERTIFICATE----- + +Camerfirma Chambers of Commerce Root +==================================== +-----BEGIN CERTIFICATE----- +MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEnMCUGA1UEChMe +QUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1i +ZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAx +NjEzNDNaFw0zNzA5MzAxNjEzNDRaMH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZp +cm1hIFNBIENJRiBBODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3Jn +MSIwIAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0BAQEFAAOC +AQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtbunXF/KGIJPov7coISjlU +xFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0dBmpAPrMMhe5cG3nCYsS4No41XQEMIwRH +NaqbYE6gZj3LJgqcQKH0XZi/caulAGgq7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jW +DA+wWFjbw2Y3npuRVDM30pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFV +d9oKDMyXroDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIGA1Ud +EwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5jaGFtYmVyc2lnbi5v +cmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p26EpW1eLTXYGduHRooowDgYDVR0P +AQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hh +bWJlcnNpZ24ub3JnMCcGA1UdEgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYD +VR0gBFEwTzBNBgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz +aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEBAAxBl8IahsAi +fJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZdp0AJPaxJRUXcLo0waLIJuvvD +L8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wN +UPf6s+xCX6ndbcj0dc97wXImsQEcXCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/n +ADydb47kMgkdTXg0eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1 +erfutGWaIZDgqtCYvDi1czyL+Nw= +-----END CERTIFICATE----- + +Camerfirma Global Chambersign Root +================================== +-----BEGIN CERTIFICATE----- +MIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEnMCUGA1UEChMe +QUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1i +ZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYx +NDE4WhcNMzcwOTMwMTYxNDE4WjB9MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJt +YSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEg +MB4GA1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUAA4IBDQAw +ggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0Mi+ITaFgCPS3CU6gSS9J +1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/sQJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8O +by4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpVeAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl +6DJWk0aJqCWKZQbua795B9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c +8lCrEqWhz0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0TAQH/ +BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1iZXJzaWduLm9yZy9j +aGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4wTcbOX60Qq+UDpfqpFDAOBgNVHQ8B +Af8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAHMCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBj +aGFtYmVyc2lnbi5vcmcwKgYDVR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9y +ZzBbBgNVHSAEVDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh +bWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0BAQUFAAOCAQEA +PDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUMbKGKfKX0j//U2K0X1S0E0T9Y +gOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXiryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJ +PJ7oKXqJ1/6v/2j1pReQvayZzKWGVwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4 +IBHNfTIzSJRUTN3cecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREes +t2d/AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A== +-----END CERTIFICATE----- + +NetLock Notary (Class A) Root +============================= +-----BEGIN CERTIFICATE----- +MIIGfTCCBWWgAwIBAgICAQMwDQYJKoZIhvcNAQEEBQAwga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQI +EwdIdW5nYXJ5MREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6 +dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9j +ayBLb3pqZWd5em9pIChDbGFzcyBBKSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNDIzMTQ0N1oX +DTE5MDIxOTIzMTQ0N1owga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQH +EwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQuMRowGAYD +VQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBLb3pqZWd5em9pIChDbGFz +cyBBKSBUYW51c2l0dmFueWtpYWRvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvHSM +D7tM9DceqQWC2ObhbHDqeLVu0ThEDaiDzl3S1tWBxdRL51uUcCbbO51qTGL3cfNk1mE7PetzozfZ +z+qMkjvN9wfcZnSX9EUi3fRc4L9t875lM+QVOr/bmJBVOMTtplVjC7B4BPTjbsE/jvxReB+SnoPC +/tmwqcm8WgD/qaiYdPv2LD4VOQ22BFWoDpggQrOxJa1+mm9dU7GrDPzr4PN6s6iz/0b2Y6LYOph7 +tqyF/7AlT3Rj5xMHpQqPBffAZG9+pyeAlt7ULoZgx2srXnN7F+eRP2QM2EsiNCubMvJIH5+hCoR6 +4sKtlz2O1cH5VqNQ6ca0+pii7pXmKgOM3wIDAQABo4ICnzCCApswDgYDVR0PAQH/BAQDAgAGMBIG +A1UdEwEB/wQIMAYBAf8CAQQwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaC +Ak1GSUdZRUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pv +bGdhbHRhdGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQu +IEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2Vn +LWJpenRvc2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0 +ZXRlbGUgYXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFz +IGxlaXJhc2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBh +IGh0dHBzOi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVu +b3J6ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1YW5jZSBh +bmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sg +Q1BTIGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFp +bCBhdCBjcHNAbmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4IBAQBIJEb3ulZv+sgoA0BO5TE5 +ayZrU3/b39/zcT0mwBQOxmd7I6gMc90Bu8bKbjc5VdXHjFYgDigKDtIqpLBJUsY4B/6+CgmM0ZjP +ytoUMaFP0jn8DxEsQ8Pdq5PHVT5HfBgaANzze9jyf1JsIPQLX2lS9O74silg6+NJMSEN1rUQQeJB +CWziGppWS3cC9qCbmieH6FUpccKQn0V4GuEVZD3QDtigdp+uxdAu6tYPVuxkf1qbFFgBJ34TUMdr +KuZoPL9coAob4Q566eKAw+np9v1sEZ7Q5SgnK1QyQhSCdeZK8CtmdWOMovsEPoMOmzbwGOQmIMOM +8CgHrTwXZoi1/baI +-----END CERTIFICATE----- + +XRamp Global CA Root +==================== +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UE +BhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2Vj +dXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwHhcNMDQxMTAxMTcxNDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMx +HjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkg +U2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS638eMpSe2OAtp87ZOqCwu +IR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCPKZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMx +foArtYzAQDsRhtDLooY2YKTVMIJt2W7QDxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FE +zG+gSqmUsE3a56k0enI4qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqs +AxcZZPRaJSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNViPvry +xS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASsjVy16bYbMDYGA1UdHwQvMC0wK6Ap +oCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMC +AQEwDQYJKoZIhvcNAQEFBQADggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc +/Kh4ZzXxHfARvbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt +qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLaIR9NmXmd4c8n +nxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSyi6mx5O+aGtA9aZnuqCij4Tyz +8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQO+7ETPTsJ3xCwnR8gooJybQDJbw= +-----END CERTIFICATE----- + +Go Daddy Class 2 CA +=================== +-----BEGIN CERTIFICATE----- +MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMY +VGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkG +A1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g +RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQAD +ggENADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv +2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+qN1j3hybX2C32 +qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiOr18SPaAIBQi2XKVlOARFmR6j +YGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmY +vLEHZ6IVDd2gWMZEewo+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0O +BBYEFNLEsNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h/t2o +atTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMu +MTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwG +A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wim +PQoZ+YeAEW5p5JYXMP80kWNyOO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKt +I3lpjbi2Tc7PTMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ +HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mERdEr/VxqHD3VI +Ls9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5CufReYNnyicsbkqWletNw+vHX/b +vZ8= +-----END CERTIFICATE----- + +Starfield Class 2 CA +==================== +-----BEGIN CERTIFICATE----- +MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzElMCMGA1UEChMc +U3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZpZWxkIENsYXNzIDIg +Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBo +MQswCQYDVQQGEwJVUzElMCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAG +A1UECxMpU3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqG +SIb3DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf8MOh2tTY +bitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN+lq2cwQlZut3f+dZxkqZ +JRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVm +epsZGD3/cVE8MC5fvj13c7JdBmzDI1aaK4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSN +F4Azbl5KXZnJHoe0nRrA1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HF +MIHCMB0GA1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fRzt0f +hvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNo +bm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBDbGFzcyAyIENlcnRpZmljYXRpb24g +QXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGs +afPzWdqbAYcaT1epoXkJKtv3L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLM +PUxA2IGvd56Deruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl +xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynpVSJYACPq4xJD +KVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEYWQPJIrSPnNVeKtelttQKbfi3 +QBFGmh95DmK/D5fs4C8fF5Q= +-----END CERTIFICATE----- + +StartCom Certification Authority +================================ +-----BEGIN CERTIFICATE----- +MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMN +U3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmlu +ZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0 +NjM2WhcNMzYwOTE3MTk0NjM2WjB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRk +LjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMg +U3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZkpMyONvg45iPwbm2xPN1y +o4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rfOQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/ +Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/CJi/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/d +eMotHweXMAEtcnn6RtYTKqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt +2PZE4XNiHzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMMAv+Z +6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w+2OqqGwaVLRcJXrJ +osmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/ +untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVc +UjyJthkqcwEKDwOzEmDyei+B26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT +37uMdBNSSwIDAQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE +FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9jZXJ0LnN0YXJ0 +Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3JsLnN0YXJ0Y29tLm9yZy9zZnNj +YS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFMBgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUH +AgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRw +Oi8vY2VydC5zdGFydGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYg +U3RhcnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlhYmlsaXR5 +LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2YgdGhlIFN0YXJ0Q29tIENl +cnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFpbGFibGUgYXQgaHR0cDovL2NlcnQuc3Rh +cnRjb20ub3JnL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilT +dGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOC +AgEAFmyZ9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8jhvh +3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUWFjgKXlf2Ysd6AgXm +vB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJzewT4F+irsfMuXGRuczE6Eri8sxHk +fY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3 +fsNrarnDy0RLrHiQi+fHLB5LEUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZ +EoalHmdkrQYuL6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq +yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuCO3NJo2pXh5Tl +1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6Vum0ABj6y6koQOdjQK/W/7HW/ +lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkyShNOsF/5oirpt9P/FlUQqmMGqz9IgcgA38coro +g14= +-----END CERTIFICATE----- + +Taiwan GRCA +=========== +-----BEGIN CERTIFICATE----- +MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/MQswCQYDVQQG +EwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4X +DTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1owPzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dv +dmVybm1lbnQgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qN +w8XRIePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1qgQdW8or5 +BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKyyhwOeYHWtXBiCAEuTk8O +1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAtsF/tnyMKtsc2AtJfcdgEWFelq16TheEfO +htX7MfP6Mb40qij7cEwdScevLJ1tZqa2jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wov +J5pGfaENda1UhhXcSTvxls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7 +Q3hub/FCVGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHKYS1t +B6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoHEgKXTiCQ8P8NHuJB +O9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThNXo+EHWbNxWCWtFJaBYmOlXqYwZE8 +lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1UdDgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNV +HRMEBTADAQH/MDkGBGcqBwAEMTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg2 +09yewDL7MTqKUWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ +TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyfqzvS/3WXy6Tj +Zwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaKZEk9GhiHkASfQlK3T8v+R0F2 +Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFEJPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlU +D7gsL0u8qV1bYH+Mh6XgUmMqvtg7hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6Qz +DxARvBMB1uUO07+1EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+Hbk +Z6MmnD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WXudpVBrkk +7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44VbnzssQwmSNOXfJIoRIM3BKQ +CZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDeLMDDav7v3Aun+kbfYNucpllQdSNpc5Oy ++fwC00fmcc4QAu4njIT/rEUNE1yDMuAlpYYsfPQS +-----END CERTIFICATE----- + +Swisscom Root CA 1 +================== +-----BEGIN CERTIFICATE----- +MIIF2TCCA8GgAwIBAgIQXAuFXAvnWUHfV8w/f52oNjANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQG +EwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0YWwgQ2VydGlmaWNhdGUgU2Vy +dmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3QgQ0EgMTAeFw0wNTA4MTgxMjA2MjBaFw0yNTA4 +MTgyMjA2MjBaMGQxCzAJBgNVBAYTAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGln +aXRhbCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAxMIIC +IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0LmwqAzZuz8h+BvVM5OAFmUgdbI9m2BtRsiM +MW8Xw/qabFbtPMWRV8PNq5ZJkCoZSx6jbVfd8StiKHVFXqrWW/oLJdihFvkcxC7mlSpnzNApbjyF +NDhhSbEAn9Y6cV9Nbc5fuankiX9qUvrKm/LcqfmdmUc/TilftKaNXXsLmREDA/7n29uj/x2lzZAe +AR81sH8A25Bvxn570e56eqeqDFdvpG3FEzuwpdntMhy0XmeLVNxzh+XTF3xmUHJd1BpYwdnP2IkC +b6dJtDZd0KTeByy2dbcokdaXvij1mB7qWybJvbCXc9qukSbraMH5ORXWZ0sKbU/Lz7DkQnGMU3nn +7uHbHaBuHYwadzVcFh4rUx80i9Fs/PJnB3r1re3WmquhsUvhzDdf/X/NTa64H5xD+SpYVUNFvJbN +cA78yeNmuk6NO4HLFWR7uZToXTNShXEuT46iBhFRyePLoW4xCGQMwtI89Tbo19AOeCMgkckkKmUp +WyL3Ic6DXqTz3kvTaI9GdVyDCW4pa8RwjPWd1yAv/0bSKzjCL3UcPX7ape8eYIVpQtPM+GP+HkM5 +haa2Y0EQs3MevNP6yn0WR+Kn1dCjigoIlmJWbjTb2QK5MHXjBNLnj8KwEUAKrNVxAmKLMb7dxiNY +MUJDLXT5xp6mig/p/r+D5kNXJLrvRjSq1xIBOO0CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYw +HQYDVR0hBBYwFDASBgdghXQBUwABBgdghXQBUwABMBIGA1UdEwEB/wQIMAYBAf8CAQcwHwYDVR0j +BBgwFoAUAyUv3m+CATpcLNwroWm1Z9SM0/0wHQYDVR0OBBYEFAMlL95vggE6XCzcK6FptWfUjNP9 +MA0GCSqGSIb3DQEBBQUAA4ICAQA1EMvspgQNDQ/NwNurqPKIlwzfky9NfEBWMXrrpA9gzXrzvsMn +jgM+pN0S734edAY8PzHyHHuRMSG08NBsl9Tpl7IkVh5WwzW9iAUPWxAaZOHHgjD5Mq2eUCzneAXQ +MbFamIp1TpBcahQq4FJHgmDmHtqBsfsUC1rxn9KVuj7QG9YVHaO+htXbD8BJZLsuUBlL0iT43R4H +VtA4oJVwIHaM190e3p9xxCPvgxNcoyQVTSlAPGrEqdi3pkSlDfTgnXceQHAm/NrZNuR55LU/vJtl +vrsRls/bxig5OgjOR1tTWsWZ/l2p3e9M1MalrQLmjAcSHm8D0W+go/MpvRLHUKKwf4ipmXeascCl +OS5cfGniLLDqN2qk4Vrh9VDlg++luyqI54zb/W1elxmofmZ1a3Hqv7HHb6D0jqTsNFFbjCYDcKF3 +1QESVwA12yPeDooomf2xEG9L/zgtYE4snOtnta1J7ksfrK/7DZBaZmBwXarNeNQk7shBoJMBkpxq +nvy5JMWzFYJ+vq6VK+uxwNrjAWALXmmshFZhvnEX/h0TD/7Gh0Xp/jKgGg0TpJRVcaUWi7rKibCy +x/yP2FS1k2Kdzs9Z+z0YzirLNRWCXf9UIltxUvu3yf5gmwBBZPCqKuy2QkPOiWaByIufOVQDJdMW +NY6E0F/6MBr1mmz0DlP5OlvRHA== +-----END CERTIFICATE----- + +DigiCert Assured ID Root CA +=========================== +-----BEGIN CERTIFICATE----- +MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw +IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzEx +MTEwMDAwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL +ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0Ew +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7cJpSIqvTO +9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYPmDI2dsze3Tyoou9q+yHy +UmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW +/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpy +oeb6pNnVFzF1roV9Iq4/AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whf +GHdPAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRF +66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkq +hkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRCdWKuh+vy1dneVrOfzM4UKLkNl2Bc +EkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTffwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38Fn +SbNd67IJKusm7Xi+fT8r87cmNW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i +8b5QZ7dsvfPxH2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe ++o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== +-----END CERTIFICATE----- + +DigiCert Global Root CA +======================= +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw +HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAw +MDAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 +dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsBCSDMAZOn +TjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97nh6Vfe63SKMI2tavegw5 +BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt43C/dxC//AH2hdmoRBBYMql1GNXRor5H +4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7PT19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y +7vrTC0LUq7dBMtoM1O/4gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQAB +o2MwYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbRTLtm +8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJKoZIhvcNAQEF +BQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/EsrhMAtudXH/vTBH1jLuG2cenTnmCmr +EbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIt +tep3Sp+dWOIrWcBAI+0tKIJFPnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886 +UAb3LujEV0lsYSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- + +DigiCert High Assurance EV Root CA +================================== +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSsw +KQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAw +MFoXDTMxMTExMDAwMDAwMFowbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ +MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFu +Y2UgRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm+9S75S0t +Mqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTWPNt0OKRKzE0lgvdKpVMS +OO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEMxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3 +MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFBIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQ +NAQTXKFx01p8VdteZOE3hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUe +h10aUAsgEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB +Af8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSY +JhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3NecnzyIZgYIVyHbIUf4KmeqvxgydkAQ +V8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6zeM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFp +myPInngiK3BD41VHMWEZ71jFhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkK +mNEVX58Svnw2Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe +vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep+OkuE6N36B9K +-----END CERTIFICATE----- + +Certplus Class 2 Primary CA +=========================== +-----BEGIN CERTIFICATE----- +MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAwPTELMAkGA1UE +BhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFzcyAyIFByaW1hcnkgQ0EwHhcN +OTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2Vy +dHBsdXMxGzAZBgNVBAMTEkNsYXNzIDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBANxQltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR +5aiRVhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyLkcAbmXuZ +Vg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCdEgETjdyAYveVqUSISnFO +YFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yasH7WLO7dDWWuwJKZtkIvEcupdM5i3y95e +e++U8Rs+yskhwcWYAqqi9lt3m/V+llU0HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRME +CDAGAQH/AgEKMAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJ +YIZIAYb4QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMuY29t +L0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/AN9WM2K191EBkOvD +P9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8yfFC82x/xXp8HVGIutIKPidd3i1R +TtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMRFcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+ +7UCmnYR0ObncHoUW2ikbhiMAybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW +//1IMwrh3KWBkJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7 +l7+ijrRU +-----END CERTIFICATE----- + +DST Root CA X3 +============== +-----BEGIN CERTIFICATE----- +MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/MSQwIgYDVQQK +ExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMTDkRTVCBSb290IENBIFgzMB4X +DTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVowPzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1 +cmUgVHJ1c3QgQ28uMRcwFQYDVQQDEw5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmT +rE4Orz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEqOLl5CjH9 +UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9bxiqKqy69cK3FCxolkHRy +xXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40d +utolucbY38EVAjqr2m7xPi71XAicPNaDaeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQ +MA0GCSqGSIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69ikug +dB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXrAvHRAosZy5Q6XkjE +GB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZzR8srzJmwN0jP41ZL9c8PDHIyh8bw +RLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubS +fZGL+T0yjWW06XyxV3bqxbYoOb8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ +-----END CERTIFICATE----- + +DST ACES CA X6 +============== +-----BEGIN CERTIFICATE----- +MIIECTCCAvGgAwIBAgIQDV6ZCtadt3js2AdWO4YV2TANBgkqhkiG9w0BAQUFADBbMQswCQYDVQQG +EwJVUzEgMB4GA1UEChMXRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QxETAPBgNVBAsTCERTVCBBQ0VT +MRcwFQYDVQQDEw5EU1QgQUNFUyBDQSBYNjAeFw0wMzExMjAyMTE5NThaFw0xNzExMjAyMTE5NTha +MFsxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdDERMA8GA1UE +CxMIRFNUIEFDRVMxFzAVBgNVBAMTDkRTVCBBQ0VTIENBIFg2MIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAuT31LMmU3HWKlV1j6IR3dma5WZFcRt2SPp/5DgO0PWGSvSMmtWPuktKe1jzI +DZBfZIGxqAgNTNj50wUoUrQBJcWVHAx+PhCEdc/BGZFjz+iokYi5Q1K7gLFViYsx+tC3dr5BPTCa +pCIlF3PoHuLTrCq9Wzgh1SpL11V94zpVvddtawJXa+ZHfAjIgrrep4c9oW24MFbCswKBXy314pow +GCi4ZtPLAZZv6opFVdbgnf9nKxcCpk4aahELfrd755jWjHZvwTvbUJN+5dCOHze4vbrGn2zpfDPy +MjwmR/onJALJfh1biEITajV8fTXpLmaRcpPVMibEdPVTo7NdmvYJywIDAQABo4HIMIHFMA8GA1Ud +EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgHGMB8GA1UdEQQYMBaBFHBraS1vcHNAdHJ1c3Rkc3Qu +Y29tMGIGA1UdIARbMFkwVwYKYIZIAWUDAgEBATBJMEcGCCsGAQUFBwIBFjtodHRwOi8vd3d3LnRy +dXN0ZHN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0FDRVMtaW5kZXguaHRtbDAdBgNVHQ4EFgQU +CXIGThhDD+XWzMNqizF7eI+og7gwDQYJKoZIhvcNAQEFBQADggEBAKPYjtay284F5zLNAdMEA+V2 +5FYrnJmQ6AgwbN99Pe7lv7UkQIRJ4dEorsTCOlMwiPH1d25Ryvr/ma8kXxug/fKshMrfqfBfBC6t +Fr8hlxCBPeP/h40y3JTlR4peahPJlJU90u7INJXQgNStMgiAVDzgvVJT11J8smk/f3rPanTK+gQq +nExaBqXpIK1FZg9p8d2/6eMyi/rgwYZNcjwu2JN4Cir42NInPRmJX1p7ijvMDNpRrscL9yuwNwXs +vFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf29w4LTJxoeHtxMcfrHuBnQfO3 +oKfN5XozNmr6mis= +-----END CERTIFICATE----- + +SwissSign Gold CA - G2 +====================== +-----BEGIN CERTIFICATE----- +MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkNIMRUw +EwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2lnbiBHb2xkIENBIC0gRzIwHhcN +MDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBFMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dp +c3NTaWduIEFHMR8wHQYDVQQDExZTd2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUq +t2/876LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+bbqBHH5C +jCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c6bM8K8vzARO/Ws/BtQpg +vd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqEemA8atufK+ze3gE/bk3lUIbLtK/tREDF +ylqM2tIrfKjuvqblCqoOpd8FUrdVxyJdMmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvR +AiTysybUa9oEVeXBCsdtMDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuend +jIj3o02yMszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69yFGkO +peUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPiaG59je883WX0XaxR +7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxMgI93e2CaHt+28kgeDrpOVG2Y4OGi +GqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUWyV7lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64 +OfPAeGZe6Drn8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov +L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe645R88a7A3hfm +5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczOUYrHUDFu4Up+GC9pWbY9ZIEr +44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOf +Mke6UiI0HTJ6CVanfCU2qT1L2sCCbwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6m +Gu6uLftIdxf+u+yvGPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxp +mo/a77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCChdiDyyJk +vC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid392qgQmwLOM7XdVAyksLf +KzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEppLd6leNcG2mqeSz53OiATIgHQv2ieY2Br +NU0LbbqhPcCT4H8js1WtciVORvnSFu+wZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6Lqj +viOvrv1vA+ACOzB2+httQc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ +-----END CERTIFICATE----- + +SwissSign Silver CA - G2 +======================== +-----BEGIN CERTIFICATE----- +MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCQ0gxFTAT +BgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMB4X +DTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0NlowRzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3 +aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG +9w0BAQEFAAOCAg8AMIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644 +N0MvFz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7brYT7QbNHm ++/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieFnbAVlDLaYQ1HTWBCrpJH +6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH6ATK72oxh9TAtvmUcXtnZLi2kUpCe2Uu +MGoM9ZDulebyzYLs2aFK7PayS+VFheZteJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5h +qAaEuSh6XzjZG6k4sIN/c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5 +FZGkECwJMoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRHHTBs +ROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTfjNFusB3hB48IHpmc +celM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb65i/4z3GcRm25xBWNOHkDRUjvxF3X +CO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUF6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRB +tjpbO8tFnb0cwpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0 +cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBAHPGgeAn0i0P +4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShpWJHckRE1qTodvBqlYJ7YH39F +kWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L +3XWgwF15kIwb4FDm3jH+mHtwX6WQ2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx +/uNncqCxv1yL5PqZIseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFa +DGi8aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2Xem1ZqSqP +e97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQRdAtq/gsD/KNVV4n+Ssuu +WxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJ +DIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ub +DgEj8Z+7fNzcbBGXJbLytGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u +-----END CERTIFICATE----- + +GeoTrust Primary Certification Authority +======================================== +-----BEGIN CERTIFICATE----- +MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQG +EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMoR2VvVHJ1c3QgUHJpbWFyeSBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgx +CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQ +cmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9AWbK7hWN +b6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjAZIVcFU2Ix7e64HXprQU9 +nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE07e9GceBrAqg1cmuXm2bgyxx5X9gaBGge +RwLmnWDiNpcB3841kt++Z8dtd1k7j53WkBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGt +tm/81w7a4DSwDRp35+MImO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJKoZI +hvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ16CePbJC/kRYkRj5K +Ts4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl4b7UVXGYNTq+k+qurUKykG/g/CFN +NWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6KoKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHa +Floxt/m0cYASSJlyc1pZU8FjUjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG +1riR/aYNKxoUAT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk= +-----END CERTIFICATE----- + +thawte Primary Root CA +====================== +-----BEGIN CERTIFICATE----- +MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCBqTELMAkGA1UE +BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2 +aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv +cml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3 +MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwg +SW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMv +KGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMT +FnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCs +oPD7gFnUnMekz52hWXMJEEUMDSxuaPFsW0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ +1CRfBsDMRJSUjQJib+ta3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGc +q/gcfomk6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6Sk/K +aAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94JNqR32HuHUETVPm4p +afs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD +VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XPr87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUF +AAOCAQEAeRHAS7ORtvzw6WfUDW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeE +uzLlQRHAd9mzYJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX +xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2/qxAeeWsEG89 +jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/LHbTY5xZ3Y+m4Q6gLkH3LpVH +z7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7jVaMaA== +-----END CERTIFICATE----- + +VeriSign Class 3 Public Primary Certification Authority - G5 +============================================================ +-----BEGIN CERTIFICATE----- +MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE +BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO +ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk +IHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCB +yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln +biBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBh +dXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmlt +YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKz +j/i5Vbext0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhD +Y2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/ +Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNHiDxpg8v+R70r +fk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/ +BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2Uv +Z2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy +aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG +SIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzEp6B4Eq1iDkVwZMXnl2YtmAl+ +X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKE +KQsTb47bDN0lAtukixlE0kF6BWlKWE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiC +Km0oHw0LxOXnGiYZ4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vE +ZV8NhnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq +-----END CERTIFICATE----- + +SecureTrust CA +============== +-----BEGIN CERTIFICATE----- +MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBIMQswCQYDVQQG +EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xFzAVBgNVBAMTDlNlY3VyZVRy +dXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIzMTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAe +BgNVBAoTF1NlY3VyZVRydXN0IENvcnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQX +OZEzZum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO0gMdA+9t +DWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIaowW8xQmxSPmjL8xk037uH +GFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b +01k/unK8RCSc43Oz969XL0Imnal0ugBS8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmH +ursCAwEAAaOBnTCBmjATBgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCegJYYj +aHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ +KoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt36Z3q059c4EVlew3KW+JwULKUBRSu +SceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHf +mbx8IVQr5Fiiu1cprp6poxkmD5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZ +nMUFdAvnZyPSCPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR +3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= +-----END CERTIFICATE----- + +Secure Global CA +================ +-----BEGIN CERTIFICATE----- +MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQG +EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBH +bG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkxMjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEg +MB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwg +Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jx +YDiJiQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa/FHtaMbQ +bqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJjnIFHovdRIWCQtBJwB1g +8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnIHmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYV +HDGA76oYa8J719rO+TMg1fW9ajMtgQT7sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi +0XPnj3pDAgMBAAGjgZ0wgZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCswKaAn +oCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsGAQQBgjcVAQQDAgEA +MA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0LURYD7xh8yOOvaliTFGCRsoTciE6+ +OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXOH0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cn +CDpOGR86p1hcF895P4vkp9MmI50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/5 +3CYNv6ZHdAbYiNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc +f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW +-----END CERTIFICATE----- + +COMODO Certification Authority +============================== +-----BEGIN CERTIFICATE----- +MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCBgTELMAkGA1UE +BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG +A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNVBAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1 +dGhvcml0eTAeFw0wNjEyMDEwMDAwMDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEb +MBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFD +T01PRE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3UcEbVASY06m/weaKXTuH ++7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI2GqGd0S7WWaXUF601CxwRM/aN5VCaTww +xHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV +4EajcNxo2f8ESIl33rXp+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA +1KGzqSX+DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5OnKVI +rLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW/zAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLmNvbW9k +b2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOC +AQEAPpiem/Yb6dc5t3iuHXIYSdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CP +OGEIqB6BCsAvIC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ +RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4zJVSk/BwJVmc +IGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5ddBA6+C4OmF4O5MBKgxTMVBbkN ++8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IBZQ== +-----END CERTIFICATE----- + +Network Solutions Certificate Authority +======================================= +-----BEGIN CERTIFICATE----- +MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQG +EwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydOZXR3b3Jr +IFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMx +MjM1OTU5WjBiMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu +MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwzc7MEL7xx +jOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPPOCwGJgl6cvf6UDL4wpPT +aaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rlmGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXT +crA/vGp97Eh/jcOrqnErU2lBUzS1sLnFBgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc +/Qzpf14Dl847ABSHJ3A4qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMB +AAGjgZcwgZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwubmV0c29sc3NsLmNv +bS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3JpdHkuY3JsMA0GCSqGSIb3DQEBBQUA +A4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc86fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q +4LqILPxFzBiwmZVRDuwduIj/h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/ +GGUsyfJj4akH/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv +wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHNpGxlaKFJdlxD +ydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey +-----END CERTIFICATE----- + +WellsSecure Public Root Certificate Authority +============================================= +-----BEGIN CERTIFICATE----- +MIIEvTCCA6WgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoM +F1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYw +NAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcN +MDcxMjEzMTcwNzU0WhcNMjIxMjE0MDAwNzU0WjCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dl +bGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYD +VQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDub7S9eeKPCCGeOARBJe+rWxxTkqxtnt3CxC5FlAM1 +iGd0V+PfjLindo8796jE2yljDpFoNoqXjopxaAkH5OjUDk/41itMpBb570OYj7OeUt9tkTmPOL13 +i0Nj67eT/DBMHAGTthP796EfvyXhdDcsHqRePGj4S78NuR4uNuip5Kf4D8uCdXw1LSLWwr8L87T8 +bJVhHlfXBIEyg1J55oNjz7fLY4sR4r1e6/aN7ZVyKLSsEmLpSjPmgzKuBXWVvYSV2ypcm44uDLiB +K0HmOFafSZtsdvqKXfcBeYF8wYNABf5x/Qw/zE5gCQ5lRxAvAcAFP4/4s0HvWkJ+We/SlwxlAgMB +AAGjggE0MIIBMDAPBgNVHRMBAf8EBTADAQH/MDkGA1UdHwQyMDAwLqAsoCqGKGh0dHA6Ly9jcmwu +cGtpLndlbGxzZmFyZ28uY29tL3dzcHJjYS5jcmwwDgYDVR0PAQH/BAQDAgHGMB0GA1UdDgQWBBQm +lRkQ2eihl5H/3BnZtQQ+0nMKajCBsgYDVR0jBIGqMIGngBQmlRkQ2eihl5H/3BnZtQQ+0nMKaqGB +i6SBiDCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRww +GgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMg +Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCAQEwDQYJKoZIhvcNAQEFBQADggEBALkVsUSRzCPI +K0134/iaeycNzXK7mQDKfGYZUMbVmO2rvwNa5U3lHshPcZeG1eMd/ZDJPHV3V3p9+N701NX3leZ0 +bh08rnyd2wIDBSxxSyU+B+NemvVmFymIGjifz6pBA4SXa5M4esowRBskRDPQ5NHcKDj0E0M1NSlj +qHyita04pO2t/caaH/+Xc/77szWnk4bGdpEA5qxRFsQnMlzbc9qlk1eOPm01JghZ1edE13YgY+es +E2fDbbFwRnzVlhE9iW9dqKHrjQrawx0zbKPqZxmamX9LPYNRKh3KL4YMon4QLSvUFpULB6ouFJJJ +tylv2G0xffX8oRAHh84vWdw+WNs= +-----END CERTIFICATE----- + +COMODO ECC Certification Authority +================================== +-----BEGIN CERTIFICATE----- +MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTELMAkGA1UEBhMC +R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE +ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwHhcNMDgwMzA2MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0Ix +GzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR +Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRo +b3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSRFtSrYpn1PlILBs5BAH+X +4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0JcfRK9ChQtP6IHG4/bC8vCVlbpVsLM5ni +wz2J+Wos77LTBumjQjBAMB0GA1UdDgQWBBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VG +FAkK+qDmfQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdvGDeA +U/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= +-----END CERTIFICATE----- + +IGC/A +===== +-----BEGIN CERTIFICATE----- +MIIEAjCCAuqgAwIBAgIFORFFEJQwDQYJKoZIhvcNAQEFBQAwgYUxCzAJBgNVBAYTAkZSMQ8wDQYD +VQQIEwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVE +Q1NTSTEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZy +MB4XDTAyMTIxMzE0MjkyM1oXDTIwMTAxNzE0MjkyMlowgYUxCzAJBgNVBAYTAkZSMQ8wDQYDVQQI +EwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVEQ1NT +STEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZyMIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsh/R0GLFMzvABIaIs9z4iPf930Pfeo2aSVz2 +TqrMHLmh6yeJ8kbpO0px1R2OLc/mratjUMdUC24SyZA2xtgv2pGqaMVy/hcKshd+ebUyiHDKcMCW +So7kVc0dJ5S/znIq7Fz5cyD+vfcuiWe4u0dzEvfRNWk68gq5rv9GQkaiv6GFGvm/5P9JhfejcIYy +HF2fYPepraX/z9E0+X1bF8bc1g4oa8Ld8fUzaJ1O/Id8NhLWo4DoQw1VYZTqZDdH6nfK0LJYBcNd +frGoRpAxVs5wKpayMLh35nnAvSk7/ZR3TL0gzUEl4C7HG7vupARB0l2tEmqKm0f7yd1GQOGdPDPQ +tQIDAQABo3cwdTAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBRjAVBgNVHSAEDjAMMAoGCCqB +egF5AQEBMB0GA1UdDgQWBBSjBS8YYFDCiQrdKyFP/45OqDAxNjAfBgNVHSMEGDAWgBSjBS8YYFDC +iQrdKyFP/45OqDAxNjANBgkqhkiG9w0BAQUFAAOCAQEABdwm2Pp3FURo/C9mOnTgXeQp/wYHE4RK +q89toB9RlPhJy3Q2FLwV3duJL92PoF189RLrn544pEfMs5bZvpwlqwN+Mw+VgQ39FuCIvjfwbF3Q +MZsyK10XZZOYYLxuj7GoPB7ZHPOpJkL5ZB3C55L29B5aqhlSXa/oovdgoPaN8In1buAKBQGVyYsg +Crpa/JosPL3Dt8ldeCUFP1YUmwza+zpI/pdpXsoQhvdOlgQITeywvl3cO45Pwf2aNjSaTFR+FwNI +lQgRHAdvhQh+XU3Endv7rs6y0bO4g2wdsrN58dhwmX7wEwLOXt1R0982gaEbeC9xs/FZTEYYKKuF +0mBWWg== +-----END CERTIFICATE----- + +Security Communication EV RootCA1 +================================= +-----BEGIN CERTIFICATE----- +MIIDfTCCAmWgAwIBAgIBADANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJKUDElMCMGA1UEChMc +U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEqMCgGA1UECxMhU2VjdXJpdHkgQ29tbXVuaWNh +dGlvbiBFViBSb290Q0ExMB4XDTA3MDYwNjAyMTIzMloXDTM3MDYwNjAyMTIzMlowYDELMAkGA1UE +BhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKjAoBgNVBAsTIVNl +Y3VyaXR5IENvbW11bmljYXRpb24gRVYgUm9vdENBMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBALx/7FebJOD+nLpCeamIivqA4PUHKUPqjgo0No0c+qe1OXj/l3X3L+SqawSERMqm4miO +/VVQYg+kcQ7OBzgtQoVQrTyWb4vVog7P3kmJPdZkLjjlHmy1V4qe70gOzXppFodEtZDkBp2uoQSX +WHnvIEqCa4wiv+wfD+mEce3xDuS4GBPMVjZd0ZoeUWs5bmB2iDQL87PRsJ3KYeJkHcFGB7hj3R4z +ZbOOCVVSPbW9/wfrrWFVGCypaZhKqkDFMxRldAD5kd6vA0jFQFTcD4SQaCDFkpbcLuUCRarAX1T4 +bepJz11sS6/vmsJWXMY1VkJqMF/Cq/biPT+zyRGPMUzXn0kCAwEAAaNCMEAwHQYDVR0OBBYEFDVK +9U2vP9eCOKyrcWUXdYydVZPmMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqG +SIb3DQEBBQUAA4IBAQCoh+ns+EBnXcPBZsdAS5f8hxOQWsTvoMpfi7ent/HWtWS3irO4G8za+6xm +iEHO6Pzk2x6Ipu0nUBsCMCRGef4Eh3CXQHPRwMFXGZpppSeZq51ihPZRwSzJIxXYKLerJRO1RuGG +Av8mjMSIkh1W/hln8lXkgKNrnKt34VFxDSDbEJrbvXZ5B3eZKK2aXtqxT0QsNY6llsf9g/BYxnnW +mHyojf6GPgcWkuF75x3sM3Z+Qi5KhfmRiWiEA4Glm5q+4zfFVKtWOxgtQaQM+ELbmaDgcm+7XeEW +T1MKZPlO9L9OVL14bIjqv5wTJMJwaaJ/D8g8rQjJsJhAoyrniIPtd490 +-----END CERTIFICATE----- + +OISTE WISeKey Global Root GA CA +=============================== +-----BEGIN CERTIFICATE----- +MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCBijELMAkGA1UE +BhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHlyaWdodCAoYykgMjAwNTEiMCAG +A1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBH +bG9iYWwgUm9vdCBHQSBDQTAeFw0wNTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYD +VQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIw +IAYDVQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5 +IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy0+zAJs9 +Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxRVVuuk+g3/ytr6dTqvirdqFEr12bDYVxg +Asj1znJ7O7jyTmUIms2kahnBAbtzptf2w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbD +d50kc3vkDIzh2TbhmYsFmQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ +/yxViJGg4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t94B3R +LoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ +KoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOxSPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vIm +MMkQyh2I+3QZH4VFvbBsUfk2ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4 ++vg1YFkCExh8vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa +hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZiFj4A4xylNoEY +okxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ/L7fCg0= +-----END CERTIFICATE----- + +Microsec e-Szigno Root CA +========================= +-----BEGIN CERTIFICATE----- +MIIHqDCCBpCgAwIBAgIRAMy4579OKRr9otxmpRwsDxEwDQYJKoZIhvcNAQEFBQAwcjELMAkGA1UE +BhMCSFUxETAPBgNVBAcTCEJ1ZGFwZXN0MRYwFAYDVQQKEw1NaWNyb3NlYyBMdGQuMRQwEgYDVQQL +EwtlLVN6aWdubyBDQTEiMCAGA1UEAxMZTWljcm9zZWMgZS1Temlnbm8gUm9vdCBDQTAeFw0wNTA0 +MDYxMjI4NDRaFw0xNzA0MDYxMjI4NDRaMHIxCzAJBgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVz +dDEWMBQGA1UEChMNTWljcm9zZWMgTHRkLjEUMBIGA1UECxMLZS1Temlnbm8gQ0ExIjAgBgNVBAMT +GU1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQDtyADVgXvNOABHzNuEwSFpLHSQDCHZU4ftPkNEU6+r+ICbPHiN1I2uuO/TEdyB5s87lozWbxXG +d36hL+BfkrYn13aaHUM86tnsL+4582pnS4uCzyL4ZVX+LMsvfUh6PXX5qqAnu3jCBspRwn5mS6/N +oqdNAoI/gqyFxuEPkEeZlApxcpMqyabAvjxWTHOSJ/FrtfX9/DAFYJLG65Z+AZHCabEeHXtTRbjc +QR/Ji3HWVBTji1R4P770Yjtb9aPs1ZJ04nQw7wHb4dSrmZsqa/i9phyGI0Jf7Enemotb9HI6QMVJ +PqW+jqpx62z69Rrkav17fVVA71hu5tnVvCSrwe+3AgMBAAGjggQ3MIIEMzBnBggrBgEFBQcBAQRb +MFkwKAYIKwYBBQUHMAGGHGh0dHBzOi8vcmNhLmUtc3ppZ25vLmh1L29jc3AwLQYIKwYBBQUHMAKG +IWh0dHA6Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNydDAPBgNVHRMBAf8EBTADAQH/MIIBcwYD +VR0gBIIBajCCAWYwggFiBgwrBgEEAYGoGAIBAQEwggFQMCgGCCsGAQUFBwIBFhxodHRwOi8vd3d3 +LmUtc3ppZ25vLmh1L1NaU1ovMIIBIgYIKwYBBQUHAgIwggEUHoIBEABBACAAdABhAG4A+gBzAO0A +dAB2AOEAbgB5ACAA6QByAHQAZQBsAG0AZQB6AOkAcwDpAGgAZQB6ACAA6QBzACAAZQBsAGYAbwBn +AGEAZADhAHMA4QBoAG8AegAgAGEAIABTAHoAbwBsAGcA4QBsAHQAYQB0APMAIABTAHoAbwBsAGcA +4QBsAHQAYQB0AOEAcwBpACAAUwB6AGEAYgDhAGwAeQB6AGEAdABhACAAcwB6AGUAcgBpAG4AdAAg +AGsAZQBsAGwAIABlAGwAagDhAHIAbgBpADoAIABoAHQAdABwADoALwAvAHcAdwB3AC4AZQAtAHMA +egBpAGcAbgBvAC4AaAB1AC8AUwBaAFMAWgAvMIHIBgNVHR8EgcAwgb0wgbqggbeggbSGIWh0dHA6 +Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNybIaBjmxkYXA6Ly9sZGFwLmUtc3ppZ25vLmh1L0NO +PU1pY3Jvc2VjJTIwZS1Temlnbm8lMjBSb290JTIwQ0EsT1U9ZS1Temlnbm8lMjBDQSxPPU1pY3Jv +c2VjJTIwTHRkLixMPUJ1ZGFwZXN0LEM9SFU/Y2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdDtiaW5h +cnkwDgYDVR0PAQH/BAQDAgEGMIGWBgNVHREEgY4wgYuBEGluZm9AZS1zemlnbm8uaHWkdzB1MSMw +IQYDVQQDDBpNaWNyb3NlYyBlLVN6aWduw7MgUm9vdCBDQTEWMBQGA1UECwwNZS1TemlnbsOzIEhT +WjEWMBQGA1UEChMNTWljcm9zZWMgS2Z0LjERMA8GA1UEBxMIQnVkYXBlc3QxCzAJBgNVBAYTAkhV +MIGsBgNVHSMEgaQwgaGAFMegSXUWYYTbMUuE0vE3QJDvTtz3oXakdDByMQswCQYDVQQGEwJIVTER +MA8GA1UEBxMIQnVkYXBlc3QxFjAUBgNVBAoTDU1pY3Jvc2VjIEx0ZC4xFDASBgNVBAsTC2UtU3pp +Z25vIENBMSIwIAYDVQQDExlNaWNyb3NlYyBlLVN6aWdubyBSb290IENBghEAzLjnv04pGv2i3Gal +HCwPETAdBgNVHQ4EFgQUx6BJdRZhhNsxS4TS8TdAkO9O3PcwDQYJKoZIhvcNAQEFBQADggEBANMT +nGZjWS7KXHAM/IO8VbH0jgdsZifOwTsgqRy7RlRw7lrMoHfqaEQn6/Ip3Xep1fvj1KcExJW4C+FE +aGAHQzAxQmHl7tnlJNUb3+FKG6qfx1/4ehHqE5MAyopYse7tDk2016g2JnzgOsHVV4Lxdbb9iV/a +86g4nzUGCM4ilb7N1fy+W955a9x6qWVmvrElWl/tftOsRm1M9DKHtCAE4Gx4sHfRhUZLphK3dehK +yVZs15KrnfVJONJPU+NVkBHbmJbGSfI+9J8b4PeI3CVimUTYc78/MPMMNz7UwiiAc7EBt51alhQB +S6kRnSlqLtBdgcDPsiBDxwPgN05dCtxZICU= +-----END CERTIFICATE----- + +Certigna +======== +-----BEGIN CERTIFICATE----- +MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNVBAYTAkZSMRIw +EAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4XDTA3MDYyOTE1MTMwNVoXDTI3 +MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwI +Q2VydGlnbmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7q +XOEm7RFHYeGifBZ4QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyH +GxnygQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbwzBfsV1/p +ogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q130yGLMLLGq/jj8UEYkg +DncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKf +Irjxwo1p3Po6WAbfAgMBAAGjgbwwgbkwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQ +tCRZvgHyUtVF9lo53BEwZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJ +BgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzjAQ/J +SP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG9w0BAQUFAAOCAQEA +hQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8hbV6lUmPOEvjvKtpv6zf+EwLHyzs+ +ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFncfca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1klu +PBS1xp81HlDQwY9qcEQCYsuuHWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY +1gkIl2PlwS6wt0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw +WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== +-----END CERTIFICATE----- + +Deutsche Telekom Root CA 2 +========================== +-----BEGIN CERTIFICATE----- +MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMT +RGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEG +A1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENBIDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5 +MjM1OTAwWjBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0G +A1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBS +b290IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEUha88EOQ5 +bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhCQN/Po7qCWWqSG6wcmtoI +KyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1MjwrrFDa1sPeg5TKqAyZMg4ISFZbavva4VhY +AUlfckE8FQYBjl2tqriTtM2e66foai1SNNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aK +Se5TBY8ZTNXeWHmb0mocQqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTV +jlsB9WoHtxa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAPBgNV +HRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAlGRZrTlk5ynr +E/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756AbrsptJh6sTtU6zkXR34ajgv8HzFZMQSy +zhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpaIzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8 +rZ7/gFnkm0W09juwzTkZmDLl6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4G +dyd1Lx+4ivn+xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU +Cm26OWMohpLzGITY+9HPBVZkVw== +-----END CERTIFICATE----- + +Cybertrust Global Root +====================== +-----BEGIN CERTIFICATE----- +MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYGA1UEChMPQ3li +ZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBSb290MB4XDTA2MTIxNTA4 +MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQD +ExZDeWJlcnRydXN0IEdsb2JhbCBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA ++Mi8vRRQZhP/8NN57CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW +0ozSJ8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2yHLtgwEZL +AfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iPt3sMpTjr3kfb1V05/Iin +89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNzFtApD0mpSPCzqrdsxacwOUBdrsTiXSZT +8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAYXSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2 +MDSgMqAwhi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3JsMB8G +A1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUAA4IBAQBW7wojoFRO +lZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMjWqd8BfP9IjsO0QbE2zZMcwSO5bAi +5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUxXOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2 +hO0j9n0Hq0V+09+zv+mKts2oomcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+T +X3EJIrduPuocA06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW +WL1WMRJOEcgh4LMRkWXbtKaIOM5V +-----END CERTIFICATE----- + +ePKI Root Certification Authority +================================= +-----BEGIN CERTIFICATE----- +MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQG +EwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0ZC4xKjAoBgNVBAsMIWVQS0kg +Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMx +MjdaMF4xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEq +MCgGA1UECwwhZVBLSSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAHSyZbCUNs +IZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAhijHyl3SJCRImHJ7K2RKi +lTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3XDZoTM1PRYfl61dd4s5oz9wCGzh1NlDiv +qOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX +12ruOzjjK9SXDrkb5wdJfzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0O +WQqraffAsgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uUWH1+ +ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLSnT0IFaUQAS2zMnao +lQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pHdmX2Os+PYhcZewoozRrSgx4hxyy/ +vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJipNiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXi +Zo1jDiVN1Rmy5nk3pyKdVDECAwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/Qkqi +MAwGA1UdEwQFMAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH +ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGBuvl2ICO1J2B0 +1GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6YlPwZpVnPDimZI+ymBV3QGypzq +KOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkPJXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdV +xrsStZf0X4OFunHB2WyBEXYKCrC/gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEP +NXubrjlpC2JgQCA2j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+r +GNm65ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUBo2M3IUxE +xJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS/jQ6fbjpKdx2qcgw+BRx +gMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2zGp1iro2C6pSe3VkQw63d4k3jMdXH7Ojy +sP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTEW9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmOD +BCEIZ43ygknQW/2xzQ+DhNQ+IIX3Sj0rnP0qCglN6oH4EZw= +-----END CERTIFICATE----- + +T\xc3\x9c\x42\xC4\xB0TAK UEKAE K\xC3\xB6k Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1 - S\xC3\xBCr\xC3\xBCm 3 +============================================================================================================================= +-----BEGIN CERTIFICATE----- +MIIFFzCCA/+gAwIBAgIBETANBgkqhkiG9w0BAQUFADCCASsxCzAJBgNVBAYTAlRSMRgwFgYDVQQH +DA9HZWJ6ZSAtIEtvY2FlbGkxRzBFBgNVBAoMPlTDvHJraXllIEJpbGltc2VsIHZlIFRla25vbG9q +aWsgQXJhxZ90xLFybWEgS3VydW11IC0gVMOcQsSwVEFLMUgwRgYDVQQLDD9VbHVzYWwgRWxla3Ry +b25payB2ZSBLcmlwdG9sb2ppIEFyYcWfdMSxcm1hIEVuc3RpdMO8c8O8IC0gVUVLQUUxIzAhBgNV +BAsMGkthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppMUowSAYDVQQDDEFUw5xCxLBUQUsgVUVLQUUg +S8O2ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSAtIFPDvHLDvG0gMzAeFw0wNzA4 +MjQxMTM3MDdaFw0xNzA4MjExMTM3MDdaMIIBKzELMAkGA1UEBhMCVFIxGDAWBgNVBAcMD0dlYnpl +IC0gS29jYWVsaTFHMEUGA1UECgw+VMO8cmtpeWUgQmlsaW1zZWwgdmUgVGVrbm9sb2ppayBBcmHF +n3TEsXJtYSBLdXJ1bXUgLSBUw5xCxLBUQUsxSDBGBgNVBAsMP1VsdXNhbCBFbGVrdHJvbmlrIHZl +IEtyaXB0b2xvamkgQXJhxZ90xLFybWEgRW5zdGl0w7xzw7wgLSBVRUtBRTEjMCEGA1UECwwaS2Ft +dSBTZXJ0aWZpa2FzeW9uIE1lcmtlemkxSjBIBgNVBAMMQVTDnELEsFRBSyBVRUtBRSBLw7ZrIFNl +cnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIC0gU8O8csO8bSAzMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAim1L/xCIOsP2fpTo6iBkcK4hgb46ezzb8R1Sf1n68yJMlaCQvEhO +Eav7t7WNeoMojCZG2E6VQIdhn8WebYGHV2yKO7Rm6sxA/OOqbLLLAdsyv9Lrhc+hDVXDWzhXcLh1 +xnnRFDDtG1hba+818qEhTsXOfJlfbLm4IpNQp81McGq+agV/E5wrHur+R84EpW+sky58K5+eeROR +6Oqeyjh1jmKwlZMq5d/pXpduIF9fhHpEORlAHLpVK/swsoHvhOPc7Jg4OQOFCKlUAwUp8MmPi+oL +hmUZEdPpCSPeaJMDyTYcIW7OjGbxmTDY17PDHfiBLqi9ggtm/oLL4eAagsNAgQIDAQABo0IwQDAd +BgNVHQ4EFgQUvYiHyY/2pAoLquvF/pEjnatKijIwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF +MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAB18+kmPNOm3JpIWmgV050vQbTlswyb2zrgxvMTfvCr4 +N5EY3ATIZJkrGG2AA1nJrvhY0D7twyOfaTyGOBye79oneNGEN3GKPEs5z35FBtYt2IpNeBLWrcLT +y9LQQfMmNkqblWwM7uXRQydmwYj3erMgbOqwaSvHIOgMA8RBBZniP+Rr+KCGgceExh/VS4ESshYh +LBOhgLJeDEoTniDYYkCrkOpkSi+sDQESeUWoL4cZaMjihccwsnX5OD+ywJO0a+IDRM5noN+J1q2M +dqMTw5RhK2vZbMEHCiIHhWyFJEapvj+LeISCfiQMnf2BN+MlqO02TpUsyZyQ2uypQjyttgI= +-----END CERTIFICATE----- + +Buypass Class 2 CA 1 +==================== +-----BEGIN CERTIFICATE----- +MIIDUzCCAjugAwIBAgIBATANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU +QnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3MgQ2xhc3MgMiBDQSAxMB4XDTA2 +MTAxMzEwMjUwOVoXDTE2MTAxMzEwMjUwOVowSzELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBh +c3MgQVMtOTgzMTYzMzI3MR0wGwYDVQQDDBRCdXlwYXNzIENsYXNzIDIgQ0EgMTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAIs8B0XY9t/mx8q6jUPFR42wWsE425KEHK8T1A9vNkYgxC7M +cXA0ojTTNy7Y3Tp3L8DrKehc0rWpkTSHIln+zNvnma+WwajHQN2lFYxuyHyXA8vmIPLXl18xoS83 +0r7uvqmtqEyeIWZDO6i88wmjONVZJMHCR3axiFyCO7srpgTXjAePzdVBHfCuuCkslFJgNJQ72uA4 +0Z0zPhX0kzLFANq1KWYOOngPIVJfAuWSeyXTkh4vFZ2B5J2O6O+JzhRMVB0cgRJNcKi+EAUXfh/R +uFdV7c27UsKwHnjCTTZoy1YmwVLBvXb3WNVyfh9EdrsAiR0WnVE1703CVu9r4Iw7DekCAwEAAaNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUP42aWYv8e3uco684sDntkHGA1sgwDgYDVR0P +AQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQAVGn4TirnoB6NLJzKyQJHyIdFkhb5jatLPgcIV +1Xp+DCmsNx4cfHZSldq1fyOhKXdlyTKdqC5Wq2B2zha0jX94wNWZUYN/Xtm+DKhQ7SLHrQVMdvvt +7h5HZPb3J31cKA9FxVxiXqaakZG3Uxcu3K1gnZZkOb1naLKuBctN518fV4bVIJwo+28TOPX2EZL2 +fZleHwzoq0QkKXJAPTZSr4xYkHPB7GEseaHsh7U/2k3ZIQAw3pDaDtMaSKk+hQsUi4y8QZ5q9w5w +wDX3OaJdZtB7WZ+oRxKaJyOkLY4ng5IgodcVf/EuGO70SH8vf/GhGLWhC5SgYiAynB321O+/TIho +-----END CERTIFICATE----- + +EBG Elektronik Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1 +========================================================================== +-----BEGIN CERTIFICATE----- +MIIF5zCCA8+gAwIBAgIITK9zQhyOdAIwDQYJKoZIhvcNAQEFBQAwgYAxODA2BgNVBAMML0VCRyBF +bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMTcwNQYDVQQKDC5FQkcg +QmlsacWfaW0gVGVrbm9sb2ppbGVyaSB2ZSBIaXptZXRsZXJpIEEuxZ4uMQswCQYDVQQGEwJUUjAe +Fw0wNjA4MTcwMDIxMDlaFw0xNjA4MTQwMDMxMDlaMIGAMTgwNgYDVQQDDC9FQkcgRWxla3Ryb25p +ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTE3MDUGA1UECgwuRUJHIEJpbGnFn2lt +IFRla25vbG9qaWxlcmkgdmUgSGl6bWV0bGVyaSBBLsWeLjELMAkGA1UEBhMCVFIwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQDuoIRh0DpqZhAy2DE4f6en5f2h4fuXd7hxlugTlkaDT7by +X3JWbhNgpQGR4lvFzVcfd2NR/y8927k/qqk153nQ9dAktiHq6yOU/im/+4mRDGSaBUorzAzu8T2b +gmmkTPiab+ci2hC6X5L8GCcKqKpE+i4stPtGmggDg3KriORqcsnlZR9uKg+ds+g75AxuetpX/dfr +eYteIAbTdgtsApWjluTLdlHRKJ2hGvxEok3MenaoDT2/F08iiFD9rrbskFBKW5+VQarKD7JK/oCZ +TqNGFav4c0JqwmZ2sQomFd2TkuzbqV9UIlKRcF0T6kjsbgNs2d1s/OsNA/+mgxKb8amTD8UmTDGy +Y5lhcucqZJnSuOl14nypqZoaqsNW2xCaPINStnuWt6yHd6i58mcLlEOzrz5z+kI2sSXFCjEmN1Zn +uqMLfdb3ic1nobc6HmZP9qBVFCVMLDMNpkGMvQQxahByCp0OLna9XvNRiYuoP1Vzv9s6xiQFlpJI +qkuNKgPlV5EQ9GooFW5Hd4RcUXSfGenmHmMWOeMRFeNYGkS9y8RsZteEBt8w9DeiQyJ50hBs37vm +ExH8nYQKE3vwO9D8owrXieqWfo1IhR5kX9tUoqzVegJ5a9KK8GfaZXINFHDk6Y54jzJ0fFfy1tb0 +Nokb+Clsi7n2l9GkLqq+CxnCRelwXQIDAJ3Zo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB +/wQEAwIBBjAdBgNVHQ4EFgQU587GT/wWZ5b6SqMHwQSny2re2kcwHwYDVR0jBBgwFoAU587GT/wW +Z5b6SqMHwQSny2re2kcwDQYJKoZIhvcNAQEFBQADggIBAJuYml2+8ygjdsZs93/mQJ7ANtyVDR2t +FcU22NU57/IeIl6zgrRdu0waypIN30ckHrMk2pGI6YNw3ZPX6bqz3xZaPt7gyPvT/Wwp+BVGoGgm +zJNSroIBk5DKd8pNSe/iWtkqvTDOTLKBtjDOWU/aWR1qeqRFsIImgYZ29fUQALjuswnoT4cCB64k +XPBfrAowzIpAoHMEwfuJJPaaHFy3PApnNgUIMbOv2AFoKuB4j3TeuFGkjGwgPaL7s9QJ/XvCgKqT +bCmYIai7FvOpEl90tYeY8pUm3zTvilORiF0alKM/fCL414i6poyWqD1SNGKfAB5UVUJnxk1Gj7sU +RT0KlhaOEKGXmdXTMIXM3rRyt7yKPBgpaP3ccQfuJDlq+u2lrDgv+R4QDgZxGhBM/nV+/x5XOULK +1+EVoVZVWRvRo68R2E7DpSvvkL/A7IITW43WciyTTo9qKd+FPNMN4KIYEsxVL0e3p5sC/kH2iExt +2qkBR4NkJ2IQgtYSe14DHzSpyZH+r11thie3I6p1GMog57AP14kOpmciY/SDQSsGS7tY1dHXt7kQ +Y9iJSrSq3RZj9W6+YKH47ejWkE8axsWgKdOnIaj1Wjz3x0miIZpKlVIglnKaZsv30oZDfCK+lvm9 +AahH3eU7QPl1K5srRmSGjR70j/sHd9DqSaIcjVIUpgqT +-----END CERTIFICATE----- + +certSIGN ROOT CA +================ +-----BEGIN CERTIFICATE----- +MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYTAlJPMREwDwYD +VQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTAeFw0wNjA3MDQxNzIwMDRa +Fw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UE +CxMQY2VydFNJR04gUk9PVCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7I +JUqOtdu0KBuqV5Do0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHH +rfAQUySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5dRdY4zTW2 +ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQOA7+j0xbm0bqQfWwCHTD +0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwvJoIQ4uNllAoEwF73XVv4EOLQunpL+943 +AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B +Af8EBAMCAcYwHQYDVR0OBBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IB +AQA+0hyJLjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecYMnQ8 +SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ44gx+FkagQnIl6Z0 +x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6IJd1hJyMctTEHBDa0GpC9oHRxUIlt +vBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNwi/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7Nz +TogVZ96edhBiIL5VaZVDADlN9u6wWk5JRFRYX0KD +-----END CERTIFICATE----- + +CNNIC ROOT +========== +-----BEGIN CERTIFICATE----- +MIIDVTCCAj2gAwIBAgIESTMAATANBgkqhkiG9w0BAQUFADAyMQswCQYDVQQGEwJDTjEOMAwGA1UE +ChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwHhcNMDcwNDE2MDcwOTE0WhcNMjcwNDE2MDcw +OTE0WjAyMQswCQYDVQQGEwJDTjEOMAwGA1UEChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1Qw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDTNfc/c3et6FtzF8LRb+1VvG7q6KR5smzD +o+/hn7E7SIX1mlwhIhAsxYLO2uOabjfhhyzcuQxauohV3/2q2x8x6gHx3zkBwRP9SFIhxFXf2tiz +VHa6dLG3fdfA6PZZxU3Iva0fFNrfWEQlMhkqx35+jq44sDB7R3IJMfAw28Mbdim7aXZOV/kbZKKT +VrdvmW7bCgScEeOAH8tjlBAKqeFkgjH5jCftppkA9nCTGPihNIaj3XrCGHn2emU1z5DrvTOTn1Or +czvmmzQgLx3vqR1jGqCA2wMv+SYahtKNu6m+UjqHZ0gNv7Sg2Ca+I19zN38m5pIEo3/PIKe38zrK +y5nLAgMBAAGjczBxMBEGCWCGSAGG+EIBAQQEAwIABzAfBgNVHSMEGDAWgBRl8jGtKvf33VKWCscC +wQ7vptU7ETAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIB/jAdBgNVHQ4EFgQUZfIxrSr3991S +lgrHAsEO76bVOxEwDQYJKoZIhvcNAQEFBQADggEBAEs17szkrr/Dbq2flTtLP1se31cpolnKOOK5 +Gv+e5m4y3R6u6jW39ZORTtpC4cMXYFDy0VwmuYK36m3knITnA3kXr5g9lNvHugDnuL8BV8F3RTIM +O/G0HAiw/VGgod2aHRM2mm23xzy54cXZF/qD1T0VoDy7HgviyJA/qIYM/PmLXoXLT1tLYhFHxUV8 +BS9BsZ4QaRuZluBVeftOhpm4lNqGOGqTo+fLbuXf6iFViZx9fX+Y9QCJ7uOEwFyWtcVG6kbghVW2 +G8kS1sHNzYDzAgE8yGnLRUhj2JTQ7IUOO04RZfSCjKY9ri4ilAnIXOo8gV0WKgOXFlUJ24pBgp5m +mxE= +-----END CERTIFICATE----- + +ApplicationCA - Japanese Government +=================================== +-----BEGIN CERTIFICATE----- +MIIDoDCCAoigAwIBAgIBMTANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJKUDEcMBoGA1UEChMT +SmFwYW5lc2UgR292ZXJubWVudDEWMBQGA1UECxMNQXBwbGljYXRpb25DQTAeFw0wNzEyMTIxNTAw +MDBaFw0xNzEyMTIxNTAwMDBaMEMxCzAJBgNVBAYTAkpQMRwwGgYDVQQKExNKYXBhbmVzZSBHb3Zl +cm5tZW50MRYwFAYDVQQLEw1BcHBsaWNhdGlvbkNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAp23gdE6Hj6UG3mii24aZS2QNcfAKBZuOquHMLtJqO8F6tJdhjYq+xpqcBrSGUeQ3DnR4 +fl+Kf5Sk10cI/VBaVuRorChzoHvpfxiSQE8tnfWuREhzNgaeZCw7NCPbXCbkcXmP1G55IrmTwcrN +wVbtiGrXoDkhBFcsovW8R0FPXjQilbUfKW1eSvNNcr5BViCH/OlQR9cwFO5cjFW6WY2H/CPek9AE +jP3vbb3QesmlOmpyM8ZKDQUXKi17safY1vC+9D/qDihtQWEjdnjDuGWk81quzMKq2edY3rZ+nYVu +nyoKb58DKTCXKB28t89UKU5RMfkntigm/qJj5kEW8DOYRwIDAQABo4GeMIGbMB0GA1UdDgQWBBRU +WssmP3HMlEYNllPqa0jQk/5CdTAOBgNVHQ8BAf8EBAMCAQYwWQYDVR0RBFIwUKROMEwxCzAJBgNV +BAYTAkpQMRgwFgYDVQQKDA/ml6XmnKzlm73mlL/lupwxIzAhBgNVBAsMGuOCouODl+ODquOCseOD +vOOCt+ODp+ODs0NBMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADlqRHZ3ODrs +o2dGD/mLBqj7apAxzn7s2tGJfHrrLgy9mTLnsCTWw//1sogJhyzjVOGjprIIC8CFqMjSnHH2HZ9g +/DgzE+Ge3Atf2hZQKXsvcJEPmbo0NI2VdMV+eKlmXb3KIXdCEKxmJj3ekav9FfBv7WxfEPjzFvYD +io+nEhEMy/0/ecGc/WLuo89UDNErXxc+4z6/wCs+CZv+iKZ+tJIX/COUgb1up8WMwusRRdv4QcmW +dupwX3kSa+SjB1oF7ydJzyGfikwJcGapJsErEU4z0g781mzSDjJkaP+tBXhfAx2o45CsJOAPQKdL +rosot4LKGAfmt1t06SAZf7IbiVQ= +-----END CERTIFICATE----- + +GeoTrust Primary Certification Authority - G3 +============================================= +-----BEGIN CERTIFICATE----- +MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UE +BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA4IEdlb1RydXN0 +IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFy +eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIz +NTk1OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAo +YykgMjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMT +LUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz+uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5j +K/BGvESyiaHAKAxJcCGVn2TAppMSAmUmhsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdE +c5IiaacDiGydY8hS2pgn5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3C +IShwiP/WJmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exALDmKu +dlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZChuOl1UcCAwEAAaNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMR5yo6hTgMdHNxr +2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IBAQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9 +cr5HqQ6XErhK8WTTOd8lNNTBzU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbE +Ap7aDHdlDkQNkv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD +AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUHSJsMC8tJP33s +t/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2Gspki4cErx5z481+oghLrGREt +-----END CERTIFICATE----- + +thawte Primary Root CA - G2 +=========================== +-----BEGIN CERTIFICATE----- +MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDELMAkGA1UEBhMC +VVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMpIDIwMDcgdGhhd3RlLCBJbmMu +IC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3Qg +Q0EgLSBHMjAeFw0wNzExMDUwMDAwMDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEV +MBMGA1UEChMMdGhhd3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBG +b3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAt +IEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/BebfowJPDQfGAFG6DAJS +LSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6papu+7qzcMBniKI11KOasf2twu8x+qi5 +8/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU +mtgAMADna3+FGO6Lts6KDPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUN +G4k8VIZ3KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41oxXZ3K +rr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg== +-----END CERTIFICATE----- + +thawte Primary Root CA - G3 +=========================== +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCBrjELMAkGA1UE +BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2 +aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv +cml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0w +ODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh +d3RlLCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uMTgwNgYD +VQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIG +A1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAsr8nLPvb2FvdeHsbnndmgcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2At +P0LMqmsywCPLLEHd5N/8YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC ++BsUa0Lfb1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS99irY +7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2SzhkGcuYMXDhpxwTW +vGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUkOQIDAQABo0IwQDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJ +KoZIhvcNAQELBQADggEBABpA2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweK +A3rD6z8KLFIWoCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu +t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7cKUGRIjxpp7sC +8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fMm7v/OeZWYdMKp8RcTGB7BXcm +er/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZuMdRAGmI0Nj81Aa6sY6A= +-----END CERTIFICATE----- + +GeoTrust Primary Certification Authority - G2 +============================================= +-----BEGIN CERTIFICATE----- +MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA3IEdlb1RydXN0IElu +Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1 +OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg +MjAwNyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMTLUdl +b1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjB2MBAGByqGSM49AgEG +BSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcLSo17VDs6bl8VAsBQps8lL33KSLjHUGMc +KiEIfJo22Av+0SbFWDEwKCXzXV2juLaltJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYD +VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+ +EVXVMAoGCCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGTqQ7m +ndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBuczrD6ogRLQy7rQkgu2 +npaqBA+K +-----END CERTIFICATE----- + +VeriSign Universal Root Certification Authority +=============================================== +-----BEGIN CERTIFICATE----- +MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCBvTELMAkGA1UE +BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO +ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk +IHVzZSBvbmx5MTgwNgYDVQQDEy9WZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9u +IEF1dGhvcml0eTAeFw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJV +UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv +cmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj +1mCOkdeQmIN65lgZOIzF9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGP +MiJhgsWHH26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+HLL72 +9fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN/BMReYTtXlT2NJ8I +AfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPTrJ9VAMf2CGqUuV/c4DPxhGD5WycR +tPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0G +CCsGAQUFBwEMBGEwX6FdoFswWTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2O +a8PPgGrUSBgsexkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud +DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4sAPmLGd75JR3 +Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+seQxIcaBlVZaDrHC1LGmWazx +Y8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTx +P/jgdFcrGJ2BtMQo2pSXpXDrrB2+BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+P +wGZsY6rp2aQW9IHRlRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4 +mJO37M2CYfE45k+XmCpajQ== +-----END CERTIFICATE----- + +VeriSign Class 3 Public Primary Certification Authority - G4 +============================================================ +-----BEGIN CERTIFICATE----- +MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjELMAkGA1UEBhMC +VVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3 +b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVz +ZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjEL +MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBU +cnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRo +b3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5 +IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8 +Utpkmw4tXNherJI9/gHmGUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGz +rl0Bp3vefLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEw +HzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24u +Y29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMWkf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMD +A2gAMGUCMGYhDBgmYFo4e1ZC4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIx +AJw9SDkjOVgaFRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA== +-----END CERTIFICATE----- + +NetLock Arany (Class Gold) Fล‘tanรบsรญtvรกny +============================================ +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQGEwJIVTERMA8G +A1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3MDUGA1UECwwuVGFuw7pzw610 +dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBB +cmFueSAoQ2xhc3MgR29sZCkgRsWRdGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgx +MjA2MTUwODIxWjCBpzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxO +ZXRMb2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlmaWNhdGlv +biBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNzIEdvbGQpIEbFkXRhbsO6 +c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxCRec75LbRTDofTjl5Bu +0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrTlF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw +/HpYzY6b7cNGbIRwXdrzAZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAk +H3B5r9s5VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRGILdw +fzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2BJtr+UBdADTHLpl1 +neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAGAQH/AgEEMA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2MU9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwW +qZw8UQCgwBEIBaeZ5m8BiFRhbvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTta +YtOUZcTh5m2C+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC +bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2FuLjbvrW5Kfna +NwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu +dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= +-----END CERTIFICATE----- + +Staat der Nederlanden Root CA - G2 +================================== +-----BEGIN CERTIFICATE----- +MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJOTDEeMBwGA1UE +CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFhdCBkZXIgTmVkZXJsYW5kZW4g +Um9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oXDTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMC +TkwxHjAcBgNVBAoMFVN0YWF0IGRlciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5l +ZGVybGFuZGVuIFJvb3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ +5291qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8SpuOUfiUtn +vWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPUZ5uW6M7XxgpT0GtJlvOj +CwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvEpMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiil +e7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCR +OME4HYYEhLoaJXhena/MUGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpI +CT0ugpTNGmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy5V65 +48r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv6q012iDTiIJh8BIi +trzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEKeN5KzlW/HdXZt1bv8Hb/C3m1r737 +qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMB +AAGjgZcwgZQwDwYDVR0TAQH/BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcC +ARYxaHR0cDovL3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV +HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqGSIb3DQEBCwUA +A4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLySCZa59sCrI2AGeYwRTlHSeYAz ++51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwj +f/ST7ZwaUb7dRUG/kSS0H4zpX897IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaN +kqbG9AclVMwWVxJKgnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfk +CpYL+63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxLvJxxcypF +URmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkmbEgeqmiSBeGCc1qb3Adb +CG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvkN1trSt8sV4pAWja63XVECDdCcAz+3F4h +oKOKwJCcaNpQ5kUQR3i2TtJlycM33+FCY7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoV +IPVVYpbtbZNQvOSqeK3Zywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm +66+KAQ== +-----END CERTIFICATE----- + +CA Disig +======== +-----BEGIN CERTIFICATE----- +MIIEDzCCAvegAwIBAgIBATANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJTSzETMBEGA1UEBxMK +QnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwHhcNMDYw +MzIyMDEzOTM0WhcNMTYwMzIyMDEzOTM0WjBKMQswCQYDVQQGEwJTSzETMBEGA1UEBxMKQnJhdGlz +bGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCS9jHBfYj9mQGp2HvycXXxMcbzdWb6UShGhJd4NLxs/LxFWYgm +GErENx+hSkS943EE9UQX4j/8SFhvXJ56CbpRNyIjZkMhsDxkovhqFQ4/61HhVKndBpnXmjxUizkD +Pw/Fzsbrg3ICqB9x8y34dQjbYkzo+s7552oftms1grrijxaSfQUMbEYDXcDtab86wYqg6I7ZuUUo +hwjstMoVvoLdtUSLLa2GDGhibYVW8qwUYzrG0ZmsNHhWS8+2rT+MitcE5eN4TPWGqvWP+j1scaMt +ymfraHtuM6kMgiioTGohQBUgDCZbg8KpFhXAJIJdKxatymP2dACw30PEEGBWZ2NFAgMBAAGjgf8w +gfwwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUjbJJaJ1yCCW5wCf1UJNWSEZx+Y8wDgYDVR0P +AQH/BAQDAgEGMDYGA1UdEQQvMC2BE2Nhb3BlcmF0b3JAZGlzaWcuc2uGFmh0dHA6Ly93d3cuZGlz +aWcuc2svY2EwZgYDVR0fBF8wXTAtoCugKYYnaHR0cDovL3d3dy5kaXNpZy5zay9jYS9jcmwvY2Ff +ZGlzaWcuY3JsMCygKqAohiZodHRwOi8vY2EuZGlzaWcuc2svY2EvY3JsL2NhX2Rpc2lnLmNybDAa +BgNVHSAEEzARMA8GDSuBHpGT5goAAAABAQEwDQYJKoZIhvcNAQEFBQADggEBAF00dGFMrzvY/59t +WDYcPQuBDRIrRhCA/ec8J9B6yKm2fnQwM6M6int0wHl5QpNt/7EpFIKrIYwvF/k/Ji/1WcbvgAa3 +mkkp7M5+cTxqEEHA9tOasnxakZzArFvITV734VP/Q3f8nktnbNfzg9Gg4H8l37iYC5oyOGwwoPP/ +CBUz91BKez6jPiCp3C9WgArtQVCwyfTssuMmRAAOb54GvCKWU3BlxFAKRmukLyeBEicTXxChds6K +ezfqwzlhA5WYOudsiCUI/HloDYd9Yvi0X/vF2Ey9WLw/Q1vUHgFNPGO+I++MzVpQuGhU+QqZMxEA +4Z7CRneC9VkGjCFMhwnN5ag= +-----END CERTIFICATE----- + +Juur-SK +======= +-----BEGIN CERTIFICATE----- +MIIE5jCCA86gAwIBAgIEO45L/DANBgkqhkiG9w0BAQUFADBdMRgwFgYJKoZIhvcNAQkBFglwa2lA +c2suZWUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKExlBUyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMRAw +DgYDVQQDEwdKdXVyLVNLMB4XDTAxMDgzMDE0MjMwMVoXDTE2MDgyNjE0MjMwMVowXTEYMBYGCSqG +SIb3DQEJARYJcGtpQHNrLmVlMQswCQYDVQQGEwJFRTEiMCAGA1UEChMZQVMgU2VydGlmaXRzZWVy +aW1pc2tlc2t1czEQMA4GA1UEAxMHSnV1ci1TSzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAIFxNj4zB9bjMI0TfncyRsvPGbJgMUaXhvSYRqTCZUXP00B841oiqBB4M8yIsdOBSvZiF3tf +TQou0M+LI+5PAk676w7KvRhj6IAcjeEcjT3g/1tf6mTll+g/mX8MCgkzABpTpyHhOEvWgxutr2TC ++Rx6jGZITWYfGAriPrsfB2WThbkasLnE+w0R9vXW+RvHLCu3GFH+4Hv2qEivbDtPL+/40UceJlfw +UR0zlv/vWT3aTdEVNMfqPxZIe5EcgEMPPbgFPtGzlc3Yyg/CQ2fbt5PgIoIuvvVoKIO5wTtpeyDa +Tpxt4brNj3pssAki14sL2xzVWiZbDcDq5WDQn/413z8CAwEAAaOCAawwggGoMA8GA1UdEwEB/wQF +MAMBAf8wggEWBgNVHSAEggENMIIBCTCCAQUGCisGAQQBzh8BAQEwgfYwgdAGCCsGAQUFBwICMIHD +HoHAAFMAZQBlACAAcwBlAHIAdABpAGYAaQBrAGEAYQB0ACAAbwBuACAAdgDkAGwAagBhAHMAdABh +AHQAdQBkACAAQQBTAC0AaQBzACAAUwBlAHIAdABpAGYAaQB0AHMAZQBlAHIAaQBtAGkAcwBrAGUA +cwBrAHUAcwAgAGEAbABhAG0ALQBTAEsAIABzAGUAcgB0AGkAZgBpAGsAYQBhAHQAaQBkAGUAIABr +AGkAbgBuAGkAdABhAG0AaQBzAGUAawBzMCEGCCsGAQUFBwIBFhVodHRwOi8vd3d3LnNrLmVlL2Nw +cy8wKwYDVR0fBCQwIjAgoB6gHIYaaHR0cDovL3d3dy5zay5lZS9qdXVyL2NybC8wHQYDVR0OBBYE +FASqekej5ImvGs8KQKcYP2/v6X2+MB8GA1UdIwQYMBaAFASqekej5ImvGs8KQKcYP2/v6X2+MA4G +A1UdDwEB/wQEAwIB5jANBgkqhkiG9w0BAQUFAAOCAQEAe8EYlFOiCfP+JmeaUOTDBS8rNXiRTHyo +ERF5TElZrMj3hWVcRrs7EKACr81Ptcw2Kuxd/u+gkcm2k298gFTsxwhwDY77guwqYHhpNjbRxZyL +abVAyJRld/JXIWY7zoVAtjNjGr95HvxcHdMdkxuLDF2FvZkwMhgJkVLpfKG6/2SSmuz+Ne6ML678 +IIbsSt4beDI3poHSna9aEhbKmVv8b20OxaAehsmR0FyYgl9jDIpaq9iVpszLita/ZEuOyoqysOkh +Mp6qqIWYNIE5ITuoOlIyPfZrN4YGWhWY3PARZv40ILcD9EEQfTmEeZZyY7aWAuVrua0ZTbvGRNs2 +yyqcjg== +-----END CERTIFICATE----- + +Hongkong Post Root CA 1 +======================= +-----BEGIN CERTIFICATE----- +MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoT +DUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMB4XDTAzMDUx +NTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25n +IFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1 +ApzQjVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEnPzlTCeqr +auh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjhZY4bXSNmO7ilMlHIhqqh +qZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9nnV0ttgCXjqQesBCNnLsak3c78QA3xMY +V18meMjWCnl3v/evt3a5pQuEF10Q6m/hq5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNV +HRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7i +h9legYsCmEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI37pio +l7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clBoiMBdDhViw+5Lmei +IAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJsEhTkYY2sEJCehFC78JZvRZ+K88ps +T/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpOfMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilT +c4afU9hDDl3WY4JxHYB0yvbiAmvZWg== +-----END CERTIFICATE----- + +SecureSign RootCA11 +=================== +-----BEGIN CERTIFICATE----- +MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDErMCkGA1UEChMi +SmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoGA1UEAxMTU2VjdXJlU2lnbiBS +b290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSsw +KQYDVQQKEyJKYXBhbiBDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1 +cmVTaWduIFJvb3RDQTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvL +TJszi1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8h9uuywGO +wvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOVMdrAG/LuYpmGYz+/3ZMq +g6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rP +O7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitA +bpSACW22s293bzUIUPsCh8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZX +t94wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAKCh +OBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xmKbabfSVSSUOrTC4r +bnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQX5Ucv+2rIrVls4W6ng+4reV6G4pQ +Oh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWrQbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01 +y8hSyn+B/tlr0/cR7SXf+Of5pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061 +lgeLKBObjBmNQSdJQO7e5iNEOdyhIta6A/I= +-----END CERTIFICATE----- + +ACEDICOM Root +============= +-----BEGIN CERTIFICATE----- +MIIFtTCCA52gAwIBAgIIYY3HhjsBggUwDQYJKoZIhvcNAQEFBQAwRDEWMBQGA1UEAwwNQUNFRElD +T00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00xCzAJBgNVBAYTAkVTMB4XDTA4 +MDQxODE2MjQyMloXDTI4MDQxMzE2MjQyMlowRDEWMBQGA1UEAwwNQUNFRElDT00gUm9vdDEMMAoG +A1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00xCzAJBgNVBAYTAkVTMIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA/5KV4WgGdrQsyFhIyv2AVClVYyT/kGWbEHV7w2rbYgIB8hiGtXxaOLHk +WLn709gtn70yN78sFW2+tfQh0hOR2QetAQXW8713zl9CgQr5auODAKgrLlUTY4HKRxx7XBZXehuD +YAQ6PmXDzQHe3qTWDLqO3tkE7hdWIpuPY/1NFgu3e3eM+SW10W2ZEi5PGrjm6gSSrj0RuVFCPYew +MYWveVqc/udOXpJPQ/yrOq2lEiZmueIM15jO1FillUAKt0SdE3QrwqXrIhWYENiLxQSfHY9g5QYb +m8+5eaA9oiM/Qj9r+hwDezCNzmzAv+YbX79nuIQZ1RXve8uQNjFiybwCq0Zfm/4aaJQ0PZCOrfbk +HQl/Sog4P75n/TSW9R28MHTLOO7VbKvU/PQAtwBbhTIWdjPp2KOZnQUAqhbm84F9b32qhm2tFXTT +xKJxqvQUfecyuB+81fFOvW8XAjnXDpVCOscAPukmYxHqC9FK/xidstd7LzrZlvvoHpKuE1XI2Sf2 +3EgbsCTBheN3nZqk8wwRHQ3ItBTutYJXCb8gWH8vIiPYcMt5bMlL8qkqyPyHK9caUPgn6C9D4zq9 +2Fdx/c6mUlv53U3t5fZvie27k5x2IXXwkkwp9y+cAS7+UEaeZAwUswdbxcJzbPEHXEUkFDWug/Fq +TYl6+rPYLWbwNof1K1MCAwEAAaOBqjCBpzAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKaz +4SsrSbbXc6GqlPUB53NlTKxQMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUprPhKytJttdzoaqU +9QHnc2VMrFAwRAYDVR0gBD0wOzA5BgRVHSAAMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly9hY2VkaWNv +bS5lZGljb21ncm91cC5jb20vZG9jMA0GCSqGSIb3DQEBBQUAA4ICAQDOLAtSUWImfQwng4/F9tqg +aHtPkl7qpHMyEVNEskTLnewPeUKzEKbHDZ3Ltvo/Onzqv4hTGzz3gvoFNTPhNahXwOf9jU8/kzJP +eGYDdwdY6ZXIfj7QeQCM8htRM5u8lOk6e25SLTKeI6RF+7YuE7CLGLHdztUdp0J/Vb77W7tH1Pwk +zQSulgUV1qzOMPPKC8W64iLgpq0i5ALudBF/TP94HTXa5gI06xgSYXcGCRZj6hitoocf8seACQl1 +ThCojz2GuHURwCRiipZ7SkXp7FnFvmuD5uHorLUwHv4FB4D54SMNUI8FmP8sX+g7tq3PgbUhh8oI +KiMnMCArz+2UW6yyetLHKKGKC5tNSixthT8Jcjxn4tncB7rrZXtaAWPWkFtPF2Y9fwsZo5NjEFIq +nxQWWOLcpfShFosOkYuByptZ+thrkQdlVV9SH686+5DdaaVbnG0OLLb6zqylfDJKZ0DcMDQj3dcE +I2bw/FWAp/tmGYI1Z2JwOV5vx+qQQEQIHriy1tvuWacNGHk0vFQYXlPKNFHtRQrmjseCNj6nOGOp +MCwXEGCSn1WHElkQwg9naRHMTh5+Spqtr0CodaxWkHS4oJyleW/c6RrIaQXpuvoDs3zk4E7Czp3o +tkYNbn5XOmeUwssfnHdKZ05phkOTOPu220+DkdRgfks+KzgHVZhepA== +-----END CERTIFICATE----- + +Microsec e-Szigno Root CA 2009 +============================== +-----BEGIN CERTIFICATE----- +MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYDVQQGEwJIVTER +MA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jv +c2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o +dTAeFw0wOTA2MTYxMTMwMThaFw0yOTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UE +BwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUt +U3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvPkd6mJviZpWNwrZuuyjNA +fW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tccbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG +0IMZfcChEhyVbUr02MelTTMuhTlAdX4UfIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKA +pxn1ntxVUwOXewdI/5n7N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm +1HxdrtbCxkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1+rUC +AwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTLD8bf +QkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAbBgNVHREE +FDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqGSIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0o +lZMEyL/azXm4Q5DwpL7v8u8hmLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfX +I/OMn74dseGkddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 +tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c2Pm2G2JwCz02 +yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5tHMN1Rq41Bab2XD0h7lbwyYIi +LXpUq3DDfSJlgnCW +-----END CERTIFICATE----- + +GlobalSign Root CA - R3 +======================= +-----BEGIN CERTIFICATE----- +MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4GA1UECxMXR2xv +YmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh +bFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT +aWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln +bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWt +iHL8RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsTgHeMCOFJ +0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmmKPZpO/bLyCiR5Z2KYVc3 +rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zdQQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjl +OCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZXriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2 +xmmFghcCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE +FI/wS3+oLkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZURUm7 +lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMpjjM5RcOO5LlXbKr8 +EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK6fBdRoyV3XpYKBovHd7NADdBj+1E +bddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQXmcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18 +YIvDQVETI53O9zJrlAGomecsMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7r +kpeDMdmztcpHWD9f +-----END CERTIFICATE----- + +Autoridad de Certificacion Firmaprofesional CIF A62634068 +========================================================= +-----BEGIN CERTIFICATE----- +MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UEBhMCRVMxQjBA +BgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2 +MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEyMzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIw +QAYDVQQDDDlBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBB +NjI2MzQwNjgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDD +Utd9thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQMcas9UX4P +B99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefGL9ItWY16Ck6WaVICqjaY +7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15iNA9wBj4gGFrO93IbJWyTdBSTo3OxDqqH +ECNZXyAFGUftaI6SEspd/NYrspI8IM/hX68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyI +plD9amML9ZMWGxmPsu2bm8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctX +MbScyJCyZ/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirjaEbsX +LZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/TKI8xWVvTyQKmtFLK +bpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF6NkBiDkal4ZkQdU7hwxu+g/GvUgU +vzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVhOSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1Ud +EwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNH +DhpkLzCBpgYDVR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp +cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBvACAAZABlACAA +bABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBlAGwAbwBuAGEAIAAwADgAMAAx +ADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx +51tkljYyGOylMnfX40S2wBEqgLk9am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qk +R71kMrv2JYSiJ0L1ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaP +T481PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS3a/DTg4f +Jl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5kSeTy36LssUzAKh3ntLFl +osS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF3dvd6qJ2gHN99ZwExEWN57kci57q13XR +crHedUTnQn3iV2t93Jm8PYMo6oCTjcVMZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoR +saS8I8nkvof/uZS2+F0gStRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTD +KCOM/iczQ0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQBjLMi +6Et8Vcad+qMUu2WFbm5PEn4KPJ2V +-----END CERTIFICATE----- + +Izenpe.com +========== +-----BEGIN CERTIFICATE----- +MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4MQswCQYDVQQG +EwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wHhcNMDcxMjEz +MTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMu +QS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ +03rKDx6sp4boFmVqscIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAK +ClaOxdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6HLmYRY2xU ++zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFXuaOKmMPsOzTFlUFpfnXC +PCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQDyCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxT +OTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbK +F7jJeodWLBoBHmy+E60QrLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK +0GqfvEyNBjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8Lhij+ +0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIBQFqNeb+Lz0vPqhbB +leStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+HMh3/1uaD7euBUbl8agW7EekFwID +AQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2luZm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+ +SVpFTlBFIFMuQS4gLSBDSUYgQTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBG +NjIgUzgxQzBBBgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx +MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O +BBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUAA4ICAQB4pgwWSp9MiDrAyw6l +Fn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWblaQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbga +kEyrkgPH7UIBzg/YsfqikuFgba56awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8q +hT/AQKM6WfxZSzwoJNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Cs +g1lwLDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCTVyvehQP5 +aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGkLhObNA5me0mrZJfQRsN5 +nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJbUjWumDqtujWTI6cfSN01RpiyEGjkpTHC +ClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZo +Q0iy2+tzJOeRf1SktoA+naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1Z +WrOZyGlsQyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw== +-----END CERTIFICATE----- + +Chambers of Commerce Root - 2008 +================================ +-----BEGIN CERTIFICATE----- +MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYDVQQGEwJFVTFD +MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv +bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu +QS4xKTAnBgNVBAMTIENoYW1iZXJzIG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEy +Mjk1MFoXDTM4MDczMTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNl +ZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQF +EwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJl +cnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW928sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKA +XuFixrYp4YFs8r/lfTJqVKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorj +h40G072QDuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR5gN/ +ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfLZEFHcpOrUMPrCXZk +NNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05aSd+pZgvMPMZ4fKecHePOjlO+Bd5g +D2vlGts/4+EhySnB8esHnFIbAURRPHsl18TlUlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331 +lubKgdaX8ZSD6e2wsWsSaR6s+12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ +0wlf2eOKNcx5Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj +ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAxhduub+84Mxh2 +EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNVHQ4EFgQU+SSsD7K1+HnA+mCI +G8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1+HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJ +BgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNh +bWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENh +bWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDiC +CQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUH +AgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAJASryI1 +wqM58C7e6bXpeHxIvj99RZJe6dqxGfwWPJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH +3qLPaYRgM+gQDROpI9CF5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbU +RWpGqOt1glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaHFoI6 +M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2pSB7+R5KBWIBpih1 +YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MDxvbxrN8y8NmBGuScvfaAFPDRLLmF +9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QGtjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcK +zBIKinmwPQN/aUv0NCB9szTqjktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvG +nrDQWzilm1DefhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg +OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZd0jQ +-----END CERTIFICATE----- + +Global Chambersign Root - 2008 +============================== +-----BEGIN CERTIFICATE----- +MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYDVQQGEwJFVTFD +MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv +bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu +QS4xJzAlBgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMx +NDBaFw0zODA3MzExMjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUg +Y3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJ +QTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD +aGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDf +VtPkOpt2RbQT2//BthmLN0EYlVJH6xedKYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXf +XjaOcNFccUMd2drvXNL7G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0 +ZJJ0YPP2zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4ddPB +/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyGHoiMvvKRhI9lNNgA +TH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2Id3UwD2ln58fQ1DJu7xsepeY7s2M +H/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3VyJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfe +Ox2YItaswTXbo6Al/3K1dh3ebeksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSF +HTynyQbehP9r6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh +wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsogzCtLkykPAgMB +AAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQWBBS5CcqcHtvTbDprru1U8VuT +BjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDprru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UE +BhMCRVUxQzBBBgNVBAcTOk1hZHJpZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJm +aXJtYS5jb20vYWRkcmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJm +aXJtYSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiCCQDJzdPp +1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0 +dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAICIf3DekijZBZRG +/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZUohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6 +ReAJ3spED8IXDneRRXozX1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/s +dZ7LoR/xfxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVza2Mg +9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yydYhz2rXzdpjEetrHH +foUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMdSqlapskD7+3056huirRXhOukP9Du +qqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9OAP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETr +P3iZ8ntxPjzxmKfFGBI/5rsoM0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVq +c5iJWzouE4gev8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z +09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B +-----END CERTIFICATE----- + +Go Daddy Root Certificate Authority - G2 +======================================== +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT +B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHkuY29tLCBJbmMu +MTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 +MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 +b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8G +A1UEAxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKDE6bFIEMBO4Tx5oVJnyfq +9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD ++qK+ihVqf94Lw7YZFAXK6sOoBJQ7RnwyDfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutd +fMh8+7ArU6SSYmlRJQVhGkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMl +NAJWJwGRtDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEAAaNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9 +BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmXWWcDYfF+OwYxdS2hII5PZYe096ac +vNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r +5N9ss4UXnT3ZJE95kTXWXwTrgIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYV +N8Gb5DKj7Tjo2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO +LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI4uJEvlz36hz1 +-----END CERTIFICATE----- + +Starfield Root Certificate Authority - G2 +========================================= +-----BEGIN CERTIFICATE----- +MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT +B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s +b2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVsZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0 +eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAw +DgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQg +VGVjaG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZpY2F0ZSBB +dXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3twQP89o/8ArFv +W59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMgnLRJdzIpVv257IzdIvpy3Cdhl+72WoTs +bhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNk +N3mSwOxGXn/hbVNMYq/NHwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7Nf +ZTD4p7dNdloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0HZbU +JtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0GCSqGSIb3DQEBCwUAA4IBAQARWfol +TwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjUsHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx +4mcujJUDJi5DnUox9g61DLu34jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUw +F5okxBDgBPfg8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K +pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1mMpYjn0q7pBZ +c2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 +-----END CERTIFICATE----- + +Starfield Services Root Certificate Authority - G2 +================================================== +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMxEDAOBgNVBAgT +B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s +b2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVsZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRl +IEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNV +BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxT +dGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2VydmljZXMg +Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20pOsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2 +h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm28xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4Pa +hHQUw2eeBGg6345AWh1KTs9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLP +LJGmpufehRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk6mFB +rMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAwDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+qAdcwKziIorhtSpzyEZGDMA0GCSqG +SIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMIbw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPP +E95Dz+I0swSdHynVv/heyNXBve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTy +xQGjhdByPq1zqwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd +iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn0q23KXB56jza +YyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCNsSi6 +-----END CERTIFICATE----- + +AffirmTrust Commercial +====================== +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCVVMxFDAS +BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMB4XDTEw +MDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly +bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6Eqdb +DuKPHx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yrba0F8PrV +C8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPALMeIrJmqbTFeurCA+ukV6 +BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1yHp52UKqK39c/s4mT6NmgTWvRLpUHhww +MmWd5jyTXlBOeuM61G7MGvv50jeuJCqrVwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNV +HQ4EFgQUnZPGU4teyq8/nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYGXUPG +hi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNjvbz4YYCanrHOQnDi +qX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivtZ8SOyUOyXGsViQK8YvxO8rUzqrJv +0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9gN53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0kh +sUlHRUe072o0EclNmsxZt9YCnlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= +-----END CERTIFICATE----- + +AffirmTrust Networking +====================== +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UEBhMCVVMxFDAS +BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMB4XDTEw +MDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly +bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SE +Hi3yYJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbuakCNrmreI +dIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRLQESxG9fhwoXA3hA/Pe24 +/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gb +h+0t+nvujArjqWaJGctB+d1ENmHP4ndGyH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNV +HQ4EFgQUBx/S55zawm6iQLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfOtDIu +UFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzuQY0x2+c06lkh1QF6 +12S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZLgo/bNjR9eUJtGxUAArgFU2HdW23 +WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4uolu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9 +/ZFvgrG+CJPbFEfxojfHRZ48x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= +-----END CERTIFICATE----- + +AffirmTrust Premium +=================== +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UEBhMCVVMxFDAS +BgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMB4XDTEwMDEy +OTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRy +dXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEAxBLfqV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtn +BKAQJG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ+jjeRFcV +5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrSs8PhaJyJ+HoAVt70VZVs ++7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmd +GPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d770O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5R +p9EixAqnOEhss/n/fauGV+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NI +S+LI+H+SqHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S5u04 +6uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4IaC1nEWTJ3s7xgaVY5 +/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TXOwF0lkLgAOIua+rF7nKsu7/+6qqo ++Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYEFJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByv +MiPIs0laUZx2KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg +Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B8OWycvpEgjNC +6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQMKSOyARiqcTtNd56l+0OOF6S +L5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK ++4w1IX2COPKpVJEZNZOUbWo6xbLQu4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmV +BtWVyuEklut89pMFu+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFg +IxpHYoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8GKa1qF60 +g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaORtGdFNrHF+QFlozEJLUb +zxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6eKeC2uAloGRwYQw== +-----END CERTIFICATE----- + +AffirmTrust Premium ECC +======================= +-----BEGIN CERTIFICATE----- +MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMCVVMxFDASBgNV +BAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQcmVtaXVtIEVDQzAeFw0xMDAx +MjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1U +cnVzdDEgMB4GA1UEAwwXQWZmaXJtVHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAQNMF4bFZ0D0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQ +N8O9ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0GA1UdDgQW +BBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAK +BggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/VsaobgxCd05DhT1wV/GzTjxi+zygk8N53X +57hG8f2h4nECMEJZh0PUUd+60wkyWs6Iflc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKM +eQ== +-----END CERTIFICATE----- + +Certum Trusted Network CA +========================= +-----BEGIN CERTIFICATE----- +MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBMMSIwIAYDVQQK +ExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBUcnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIy +MTIwNzM3WhcNMjkxMjMxMTIwNzM3WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBU +ZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +MSIwIAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rHUV+rpDKmYYe2bg+G0jAC +l/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LMTXPb865Px1bVWqeWifrzq2jUI4ZZJ88J +J7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVUBBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4 +fOQtf/WsX+sWn7Et0brMkUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0 +cvW0QM8xAcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNVHRMB +Af8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNVHQ8BAf8EBAMCAQYw +DQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15ysHhE49wcrwn9I0j6vSrEuVUEtRCj +jSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfLI9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1 +mS1FhIrlQgnXdAIv94nYmem8J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5aj +Zt3hrvJBW8qYVoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI +03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= +-----END CERTIFICATE----- + +Certinomis - Autoritรฉ Racine +============================= +-----BEGIN CERTIFICATE----- +MIIFnDCCA4SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJGUjETMBEGA1UEChMK +Q2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxJjAkBgNVBAMMHUNlcnRpbm9taXMg +LSBBdXRvcml0w6kgUmFjaW5lMB4XDTA4MDkxNzA4Mjg1OVoXDTI4MDkxNzA4Mjg1OVowYzELMAkG +A1UEBhMCRlIxEzARBgNVBAoTCkNlcnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMSYw +JAYDVQQDDB1DZXJ0aW5vbWlzIC0gQXV0b3JpdMOpIFJhY2luZTCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAJ2Fn4bT46/HsmtuM+Cet0I0VZ35gb5j2CN2DpdUzZlMGvE5x4jYF1AMnmHa +wE5V3udauHpOd4cN5bjr+p5eex7Ezyh0x5P1FMYiKAT5kcOrJ3NqDi5N8y4oH3DfVS9O7cdxbwly +Lu3VMpfQ8Vh30WC8Tl7bmoT2R2FFK/ZQpn9qcSdIhDWerP5pqZ56XjUl+rSnSTV3lqc2W+HN3yNw +2F1MpQiD8aYkOBOo7C+ooWfHpi2GR+6K/OybDnT0K0kCe5B1jPyZOQE51kqJ5Z52qz6WKDgmi92N +jMD2AR5vpTESOH2VwnHu7XSu5DaiQ3XV8QCb4uTXzEIDS3h65X27uK4uIJPT5GHfceF2Z5c/tt9q +c1pkIuVC28+BA5PY9OMQ4HL2AHCs8MF6DwV/zzRpRbWT5BnbUhYjBYkOjUjkJW+zeL9i9Qf6lSTC +lrLooyPCXQP8w9PlfMl1I9f09bze5N/NgL+RiH2nE7Q5uiy6vdFrzPOlKO1Enn1So2+WLhl+HPNb +xxaOu2B9d2ZHVIIAEWBsMsGoOBvrbpgT1u449fCfDu/+MYHB0iSVL1N6aaLwD4ZFjliCK0wi1F6g +530mJ0jfJUaNSih8hp75mxpZuWW/Bd22Ql095gBIgl4g9xGC3srYn+Y3RyYe63j3YcNBZFgCQfna +4NH4+ej9Uji29YnfAgMBAAGjWzBZMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBQNjLZh2kS40RR9w759XkjwzspqsDAXBgNVHSAEEDAOMAwGCiqBegFWAgIAAQEwDQYJ +KoZIhvcNAQEFBQADggIBACQ+YAZ+He86PtvqrxyaLAEL9MW12Ukx9F1BjYkMTv9sov3/4gbIOZ/x +WqndIlgVqIrTseYyCYIDbNc/CMf4uboAbbnW/FIyXaR/pDGUu7ZMOH8oMDX/nyNTt7buFHAAQCva +R6s0fl6nVjBhK4tDrP22iCj1a7Y+YEq6QpA0Z43q619FVDsXrIvkxmUP7tCMXWY5zjKn2BCXwH40 +nJ+U8/aGH88bc62UeYdocMMzpXDn2NU4lG9jeeu/Cg4I58UvD0KgKxRA/yHgBcUn4YQRE7rWhh1B +CxMjidPJC+iKunqjo3M3NYB9Ergzd0A4wPpeMNLytqOx1qKVl4GbUu1pTP+A5FPbVFsDbVRfsbjv +JL1vnxHDx2TCDyhihWZeGnuyt++uNckZM6i4J9szVb9o4XVIRFb7zdNIu0eJOqxp9YDG5ERQL1TE +qkPFMTFYvZbF6nVsmnWxTfj3l/+WFvKXTej28xH5On2KOG4Ey+HTRRWqpdEdnV1j6CTmNhTih60b +WfVEm/vXd3wfAXBioSAaosUaKPQhA+4u2cGA6rnZgtZbdsLLO7XSAPCjDuGtbkD326C00EauFddE +wk01+dIL8hf2rGbVJLJP0RyZwG71fet0BLj5TXcJ17TPBzAJ8bgAVtkXFhYKK4bfjwEZGuW7gmP/ +vgt2Fl43N+bYdJeimUV5 +-----END CERTIFICATE----- + +Root CA Generalitat Valenciana +============================== +-----BEGIN CERTIFICATE----- +MIIGizCCBXOgAwIBAgIEO0XlaDANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJFUzEfMB0GA1UE +ChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJR1ZBMScwJQYDVQQDEx5Sb290 +IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwHhcNMDEwNzA2MTYyMjQ3WhcNMjEwNzAxMTUyMjQ3 +WjBoMQswCQYDVQQGEwJFUzEfMB0GA1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UE +CxMGUEtJR1ZBMScwJQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGKqtXETcvIorKA3Qdyu0togu8M1JAJke+WmmmO3I2 +F0zo37i7L3bhQEZ0ZQKQUgi0/6iMweDHiVYQOTPvaLRfX9ptI6GJXiKjSgbwJ/BXufjpTjJ3Cj9B +ZPPrZe52/lSqfR0grvPXdMIKX/UIKFIIzFVd0g/bmoGlu6GzwZTNVOAydTGRGmKy3nXiz0+J2ZGQ +D0EbtFpKd71ng+CT516nDOeB0/RSrFOyA8dEJvt55cs0YFAQexvba9dHq198aMpunUEDEO5rmXte +JajCq+TA81yc477OMUxkHl6AovWDfgzWyoxVjr7gvkkHD6MkQXpYHYTqWBLI4bft75PelAgxAgMB +AAGjggM7MIIDNzAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9vY3NwLnBraS5n +dmEuZXMwEgYDVR0TAQH/BAgwBgEB/wIBAjCCAjQGA1UdIASCAiswggInMIICIwYKKwYBBAG/VQIB +ADCCAhMwggHoBggrBgEFBQcCAjCCAdoeggHWAEEAdQB0AG8AcgBpAGQAYQBkACAAZABlACAAQwBl +AHIAdABpAGYAaQBjAGEAYwBpAPMAbgAgAFIAYQDtAHoAIABkAGUAIABsAGEAIABHAGUAbgBlAHIA +YQBsAGkAdABhAHQAIABWAGEAbABlAG4AYwBpAGEAbgBhAC4ADQAKAEwAYQAgAEQAZQBjAGwAYQBy +AGEAYwBpAPMAbgAgAGQAZQAgAFAAcgDhAGMAdABpAGMAYQBzACAAZABlACAAQwBlAHIAdABpAGYA +aQBjAGEAYwBpAPMAbgAgAHEAdQBlACAAcgBpAGcAZQAgAGUAbAAgAGYAdQBuAGMAaQBvAG4AYQBt +AGkAZQBuAHQAbwAgAGQAZQAgAGwAYQAgAHAAcgBlAHMAZQBuAHQAZQAgAEEAdQB0AG8AcgBpAGQA +YQBkACAAZABlACAAQwBlAHIAdABpAGYAaQBjAGEAYwBpAPMAbgAgAHMAZQAgAGUAbgBjAHUAZQBu +AHQAcgBhACAAZQBuACAAbABhACAAZABpAHIAZQBjAGMAaQDzAG4AIAB3AGUAYgAgAGgAdAB0AHAA +OgAvAC8AdwB3AHcALgBwAGsAaQAuAGcAdgBhAC4AZQBzAC8AYwBwAHMwJQYIKwYBBQUHAgEWGWh0 +dHA6Ly93d3cucGtpLmd2YS5lcy9jcHMwHQYDVR0OBBYEFHs100DSHHgZZu90ECjcPk+yeAT8MIGV +BgNVHSMEgY0wgYqAFHs100DSHHgZZu90ECjcPk+yeAT8oWykajBoMQswCQYDVQQGEwJFUzEfMB0G +A1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJR1ZBMScwJQYDVQQDEx5S +b290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmGCBDtF5WgwDQYJKoZIhvcNAQEFBQADggEBACRh +TvW1yEICKrNcda3FbcrnlD+laJWIwVTAEGmiEi8YPyVQqHxK6sYJ2fR1xkDar1CdPaUWu20xxsdz +Ckj+IHLtb8zog2EWRpABlUt9jppSCS/2bxzkoXHPjCpaF3ODR00PNvsETUlR4hTJZGH71BTg9J63 +NI8KJr2XXPR5OkowGcytT6CYirQxlyric21+eLj4iIlPsSKRZEv1UN4D2+XFducTZnV+ZfsBn5OH +iJ35Rld8TWCvmHMTI6QgkYH60GFmuH3Rr9ZvHmw96RH9qfmCIoaZM3Fa6hlXPZHNqcCjbgcTpsnt ++GijnsNacgmHKNHEc8RzGF9QdRYxn7fofMM= +-----END CERTIFICATE----- + +TWCA Root Certification Authority +================================= +-----BEGIN CERTIFICATE----- +MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJ +VEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMzWhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQG +EwJUVzESMBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NB +IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFEAcK0HMMx +QhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HHK3XLfJ+utdGdIzdjp9xC +oi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeXRfwZVzsrb+RH9JlF/h3x+JejiB03HFyP +4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/zrX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1r +y+UPizgN7gr8/g+YnzAx3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIB +BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkqhkiG +9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeCMErJk/9q56YAf4lC +mtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdlsXebQ79NqZp4VKIV66IIArB6nCWlW +QtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62Dlhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVY +T0bf+215WfKEIlKuD8z7fDvnaspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocny +Yh0igzyXxfkZYiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== +-----END CERTIFICATE----- + +Security Communication RootCA2 +============================== +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDElMCMGA1UEChMc +U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMeU2VjdXJpdHkgQ29tbXVuaWNh +dGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoXDTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMC +SlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3Vy +aXR5IENvbW11bmljYXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ANAVOVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGrzbl+dp++ ++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVMVAX3NuRFg3sUZdbcDE3R +3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQhNBqyjoGADdH5H5XTz+L62e4iKrFvlNV +spHEfbmwhRkGeC7bYRr6hfVKkaHnFtWOojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1K +EOtOghY6rCcMU/Gt1SSwawNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8 +QIH4D5csOPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB +CwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpFcoJxDjrSzG+ntKEj +u/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXcokgfGT+Ok+vx+hfuzU7jBBJV1uXk +3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6q +tnRGEmyR7jTV7JqR50S+kDFy1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29 +mvVXIwAHIRc/SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 +-----END CERTIFICATE----- + +EC-ACC +====== +-----BEGIN CERTIFICATE----- +MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB8zELMAkGA1UE +BhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2VydGlmaWNhY2lvIChOSUYgUS0w +ODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYD +VQQLEyxWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UE +CxMsSmVyYXJxdWlhIEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMT +BkVDLUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQGEwJFUzE7 +MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8gKE5JRiBRLTA4MDExNzYt +SSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBDZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZl +Z2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQubmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJh +cnF1aWEgRW50aXRhdHMgZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUND +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R85iK +w5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm4CgPukLjbo73FCeT +ae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaVHMf5NLWUhdWZXqBIoH7nF2W4onW4 +HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNdQlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0a +E9jD2z3Il3rucO2n5nzbcc8tlGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw +0JDnJwIDAQABo4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4opvpXY0wfwYD +VR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBodHRwczovL3d3dy5jYXRjZXJ0 +Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5l +dC92ZXJhcnJlbCAwDQYJKoZIhvcNAQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJ +lF7W2u++AVtd0x7Y/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNa +Al6kSBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhyRp/7SNVe +l+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOSAgu+TGbrIP65y7WZf+a2 +E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xlnJ2lYJU6Un/10asIbvPuW/mIPX64b24D +5EI= +-----END CERTIFICATE----- + +Hellenic Academic and Research Institutions RootCA 2011 +======================================================= +-----BEGIN CERTIFICATE----- +MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1IxRDBCBgNVBAoT +O0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9y +aXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z +IFJvb3RDQSAyMDExMB4XDTExMTIwNjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYT +AkdSMUQwQgYDVQQKEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z +IENlcnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNo +IEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPzdYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI +1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJfel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa +71HFK9+WXesyHgLacEnsbgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u +8yBRQlqD75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSPFEDH +3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNVHRMBAf8EBTADAQH/ +MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp5dgTBCPuQSUwRwYDVR0eBEAwPqA8 +MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQub3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQu +b3JnMA0GCSqGSIb3DQEBBQUAA4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVt +XdMiKahsog2p6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8 +TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7dIsXRSZMFpGD +/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8AcysNnq/onN694/BtZqhFLKPM58N +7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXIl7WdmplNsDz4SgCbZN2fOUvRJ9e4 +-----END CERTIFICATE----- + +Actalis Authentication Root CA +============================== +-----BEGIN CERTIFICATE----- +MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UEBhMCSVQxDjAM +BgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UE +AwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDky +MjExMjIwMlowazELMAkGA1UEBhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlz +IFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 +IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNvUTufClrJ +wkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX4ay8IMKx4INRimlNAJZa +by/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9KK3giq0itFZljoZUj5NDKd45RnijMCO6 +zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1f +YVEiVRvjRuPjPdA1YprbrxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2 +oxgkg4YQ51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2Fbe8l +EfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxeKF+w6D9Fz8+vm2/7 +hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4Fv6MGn8i1zeQf1xcGDXqVdFUNaBr8 +EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbnfpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5 +jF66CyCU3nuDuP/jVo23Eek7jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLY +iDrIn3hm7YnzezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt +ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQALe3KHwGCmSUyI +WOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70jsNjLiNmsGe+b7bAEzlgqqI0 +JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDzWochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKx +K3JCaKygvU5a2hi/a5iB0P2avl4VSM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+ +Xlff1ANATIGk0k9jpwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC +4yyXX04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+OkfcvHlXHo +2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7RK4X9p2jIugErsWx0Hbhz +lefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btUZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXem +OR/qnuOf0GZvBeyqdn6/axag67XH/JJULysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9 +vwGYT7JZVEc+NHt4bVaTLnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== +-----END CERTIFICATE----- + +Trustis FPS Root CA +=================== +-----BEGIN CERTIFICATE----- +MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQG +EwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQLExNUcnVzdGlzIEZQUyBSb290 +IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTExMzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNV +BAoTD1RydXN0aXMgTGltaXRlZDEcMBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQ +RUN+AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihHiTHcDnlk +H5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjjvSkCqPoc4Vu5g6hBSLwa +cY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zt +o3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlBOrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEA +AaNTMFEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAd +BgNVHQ4EFgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01GX2c +GE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmWzaD+vkAMXBJV+JOC +yinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP41BIy+Q7DsdwyhEQsb8tGD+pmQQ9P +8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZEf1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHV +l/9D7S3B2l0pKoU/rGXuhg8FjZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYl +iB6XzCGcKQENZetX2fNXlrtIzYE= +-----END CERTIFICATE----- + +StartCom Certification Authority +================================ +-----BEGIN CERTIFICATE----- +MIIHhzCCBW+gAwIBAgIBLTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMN +U3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmlu +ZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0 +NjM3WhcNMzYwOTE3MTk0NjM2WjB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRk +LjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMg +U3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZkpMyONvg45iPwbm2xPN1y +o4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rfOQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/ +Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/CJi/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/d +eMotHweXMAEtcnn6RtYTKqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt +2PZE4XNiHzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMMAv+Z +6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w+2OqqGwaVLRcJXrJ +osmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/ +untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVc +UjyJthkqcwEKDwOzEmDyei+B26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT +37uMdBNSSwIDAQABo4ICEDCCAgwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD +VR0OBBYEFE4L7xqkQFulF2mHMMo0aEPQQa7yMB8GA1UdIwQYMBaAFE4L7xqkQFulF2mHMMo0aEPQ +Qa7yMIIBWgYDVR0gBIIBUTCCAU0wggFJBgsrBgEEAYG1NwEBATCCATgwLgYIKwYBBQUHAgEWImh0 +dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cu +c3RhcnRzc2wuY29tL2ludGVybWVkaWF0ZS5wZGYwgc8GCCsGAQUFBwICMIHCMCcWIFN0YXJ0IENv +bW1lcmNpYWwgKFN0YXJ0Q29tKSBMdGQuMAMCAQEagZZMaW1pdGVkIExpYWJpbGl0eSwgcmVhZCB0 +aGUgc2VjdGlvbiAqTGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93d3cuc3RhcnRzc2wuY29t +L3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBG +cmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAgEAjo/n3JR5 +fPGFf59Jb2vKXfuM/gTFwWLRfUKKvFO3lANmMD+x5wqnUCBVJX92ehQN6wQOQOY+2IirByeDqXWm +N3PH/UvSTa0XQMhGvjt/UfzDtgUx3M2FIk5xt/JxXrAaxrqTi3iSSoX4eA+D/i+tLPfkpLst0OcN +Org+zvZ49q5HJMqjNTbOx8aHmNrs++myziebiMMEofYLWWivydsQD032ZGNcpRJvkrKTlMeIFw6T +tn5ii5B/q06f/ON1FE8qMt9bDeD1e5MNq6HPh+GlBEXoPBKlCcWw0bdT82AUuoVpaiF8H3VhFyAX +e2w7QSlc4axa0c2Mm+tgHRns9+Ww2vl5GKVFP0lDV9LdJNUso/2RjSe15esUBppMeyG7Oq0wBhjA +2MFrLH9ZXF2RsXAiV+uKa0hK1Q8p7MZAwC+ITGgBF3f0JBlPvfrhsiAhS90a2Cl9qrjeVOwhVYBs +HvUwyKMQ5bLmKhQxw4UtjJixhlpPiVktucf3HMiKf8CdBUrmQk9io20ppB+Fq9vlgcitKj1MXVuE +JnHEhV5xJMqlG2zYYdMa4FTbzrqpMrUi9nNBCV24F10OD5mQ1kfabwo6YigUZ4LZ8dCAWZvLMdib +D4x3TrVoivJs9iQOLWxwxXPR3hTQcY+203sC9uO41Alua551hDnmfyWl8kgAwKQB2j8= +-----END CERTIFICATE----- + +StartCom Certification Authority G2 +=================================== +-----BEGIN CERTIFICATE----- +MIIFYzCCA0ugAwIBAgIBOzANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJJTDEWMBQGA1UEChMN +U3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg +RzIwHhcNMTAwMTAxMDEwMDAxWhcNMzkxMjMxMjM1OTAxWjBTMQswCQYDVQQGEwJJTDEWMBQGA1UE +ChMNU3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkgRzIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2iTZbB7cgNr2Cu+EWIAOVeq8O +o1XJJZlKxdBWQYeQTSFgpBSHO839sj60ZwNq7eEPS8CRhXBF4EKe3ikj1AENoBB5uNsDvfOpL9HG +4A/LnooUCri99lZi8cVytjIl2bLzvWXFDSxu1ZJvGIsAQRSCb0AgJnooD/Uefyf3lLE3PbfHkffi +Aez9lInhzG7TNtYKGXmu1zSCZf98Qru23QumNK9LYP5/Q0kGi4xDuFby2X8hQxfqp0iVAXV16iul +Q5XqFYSdCI0mblWbq9zSOdIxHWDirMxWRST1HFSr7obdljKF+ExP6JV2tgXdNiNnvP8V4so75qbs +O+wmETRIjfaAKxojAuuKHDp2KntWFhxyKrOq42ClAJ8Em+JvHhRYW6Vsi1g8w7pOOlz34ZYrPu8H +vKTlXcxNnw3h3Kq74W4a7I/htkxNeXJdFzULHdfBR9qWJODQcqhaX2YtENwvKhOuJv4KHBnM0D4L +nMgJLvlblnpHnOl68wVQdJVznjAJ85eCXuaPOQgeWeU1FEIT/wCc976qUM/iUUjXuG+v+E5+M5iS +FGI6dWPPe/regjupuznixL0sAA7IF6wT700ljtizkC+p2il9Ha90OrInwMEePnWjFqmveiJdnxMa +z6eg6+OGCtP95paV1yPIN93EfKo2rJgaErHgTuixO/XWb/Ew1wIDAQABo0IwQDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUS8W0QGutHLOlHGVuRjaJhwUMDrYwDQYJ +KoZIhvcNAQELBQADggIBAHNXPyzVlTJ+N9uWkusZXn5T50HsEbZH77Xe7XRcxfGOSeD8bpkTzZ+K +2s06Ctg6Wgk/XzTQLwPSZh0avZyQN8gMjgdalEVGKua+etqhqaRpEpKwfTbURIfXUfEpY9Z1zRbk +J4kd+MIySP3bmdCPX1R0zKxnNBFi2QwKN4fRoxdIjtIXHfbX/dtl6/2o1PXWT6RbdejF0mCy2wl+ +JYt7ulKSnj7oxXehPOBKc2thz4bcQ///If4jXSRK9dNtD2IEBVeC2m6kMyV5Sy5UGYvMLD0w6dEG +/+gyRr61M3Z3qAFdlsHB1b6uJcDJHgoJIIihDsnzb02CVAAgp9KP5DlUFy6NHrgbuxu9mk47EDTc +nIhT76IxW1hPkWLIwpqazRVdOKnWvvgTtZ8SafJQYqz7Fzf07rh1Z2AQ+4NQ+US1dZxAF7L+/Xld +blhYXzD8AK6vM8EOTmy6p6ahfzLbOOCxchcKK5HsamMm7YnUeMx0HgX4a/6ManY5Ka5lIxKVCCIc +l85bBu4M4ru8H0ST9tg4RQUh7eStqxK2A6RCLi3ECToDZ2mEmuFZkIoohdVddLHRDiBYmxOlsGOm +7XtH/UVVMKTumtTm4ofvmMkyghEpIrwACjFeLQ/Ajulrso8uBtjRkcfGEvRM/TAXw8HaOFvjqerm +obp573PYtlNXLfbQ4ddI +-----END CERTIFICATE----- + +Buypass Class 2 Root CA +======================= +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU +QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMiBSb290IENBMB4X +DTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1owTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1 +eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1 +g1Lr6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPVL4O2fuPn +9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC911K2GScuVr1QGbNgGE41b +/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHxMlAQTn/0hpPshNOOvEu/XAFOBz3cFIqU +CqTqc/sLUegTBxj6DvEr0VQVfTzh97QZQmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeff +awrbD02TTqigzXsu8lkBarcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgI +zRFo1clrUs3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLiFRhn +Bkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRSP/TizPJhk9H9Z2vX +Uq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN9SG9dKpN6nIDSdvHXx1iY8f93ZHs +M+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxPAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD +VR0OBBYEFMmAd+BikoL1RpzzuvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF +AAOCAgEAU18h9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s +A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3tOluwlN5E40EI +osHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo+fsicdl9sz1Gv7SEr5AcD48S +aq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYd +DnkM/crqJIByw5c/8nerQyIKx+u2DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWD +LfJ6v9r9jv6ly0UsH8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0 +oyLQI+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK75t98biGC +wWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h3PFaTWwyI0PurKju7koS +CTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPzY11aWOIv4x3kqdbQCtCev9eBCfHJxyYN +rJgWVqA= +-----END CERTIFICATE----- + +Buypass Class 3 Root CA +======================= +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU +QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMyBSb290IENBMB4X +DTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFowTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1 +eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRH +sJ8YZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3EN3coTRiR +5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9tznDDgFHmV0ST9tD+leh +7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX0DJq1l1sDPGzbjniazEuOQAnFN44wOwZ +ZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH +2xc519woe2v1n/MuwU8XKhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV +/afmiSTYzIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvSO1UQ +RwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D34xFMFbG02SrZvPA +Xpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgPK9Dx2hzLabjKSWJtyNBjYt1gD1iq +j6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD +VR0OBBYEFEe4zf/lb+74suwvTg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF +AAOCAgEAACAjQTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV +cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXSIGrs/CIBKM+G +uIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2HJLw5QY33KbmkJs4j1xrG0aG +Q0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsaO5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8 +ZORK15FTAaggiG6cX0S5y2CBNOxv033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2 +KSb12tjE8nVhz36udmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz +6MkEkbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg413OEMXbug +UZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvDu79leNKGef9JOxqDDPDe +eOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq4/g7u9xN12TyUb7mqqta6THuBrxzvxNi +Cp/HuZc= +-----END CERTIFICATE----- + +T-TeleSec GlobalRoot Class 3 +============================ +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM +IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU +cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgx +MDAxMTAyOTU2WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz +dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD +ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN8ELg63iIVl6bmlQdTQyK +9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/RLyTPWGrTs0NvvAgJ1gORH8EGoel15YU +NpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZF +iP0Zf3WHHx+xGwpzJFu5ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W +0eDrXltMEnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGjQjBA +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1A/d2O2GCahKqGFPr +AyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOyWL6ukK2YJ5f+AbGwUgC4TeQbIXQb +fsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzT +ucpH9sry9uetuUg/vBa3wW306gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7h +P0HHRwA11fXT91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml +e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4pTpPDpFQUWw== +-----END CERTIFICATE----- + +EE Certification Centre Root CA +=============================== +-----BEGIN CERTIFICATE----- +MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQG +EwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1czEoMCYGA1UEAwwfRUUgQ2Vy +dGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYGCSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIw +MTAxMDMwMTAxMDMwWhgPMjAzMDEyMTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlB +UyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRy +ZSBSb290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUyeuuOF0+W2Ap7kaJjbMeM +TC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvObntl8jixwKIy72KyaOBhU8E2lf/slLo2 +rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIwWFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw +93X2PaRka9ZP585ArQ/dMtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtN +P2MbRMNE1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/zQas8fElyalL1BSZ +MEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEF +BQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEFBQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+Rj +xY6hUFaTlrg4wCQiZrxTFGGVv9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqM +lIpPnTX/dqQGE5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u +uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIWiAYLtqZLICjU +3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/vGVCJYMzpJJUPwssd8m92kMfM +dcGWxZ0= +-----END CERTIFICATE----- + +TURKTRUST Certificate Services Provider Root 2007 +================================================= +-----BEGIN CERTIFICATE----- +MIIEPTCCAyWgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvzE/MD0GA1UEAww2VMOcUktUUlVTVCBF +bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEP +MA0GA1UEBwwGQW5rYXJhMV4wXAYDVQQKDFVUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUg +QmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgQXJhbMSxayAyMDA3MB4X +DTA3MTIyNTE4MzcxOVoXDTE3MTIyMjE4MzcxOVowgb8xPzA9BgNVBAMMNlTDnFJLVFJVU1QgRWxl +a3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTELMAkGA1UEBhMCVFIxDzAN +BgNVBAcMBkFua2FyYTFeMFwGA1UECgxVVMOcUktUUlVTVCBCaWxnaSDEsGxldGnFn2ltIHZlIEJp +bGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkgQS7Fni4gKGMpIEFyYWzEsWsgMjAwNzCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKu3PgqMyKVYFeaK7yc9SrToJdPNM8Ig3BnuiD9N +YvDdE3ePYakqtdTyuTFYKTsvP2qcb3N2Je40IIDu6rfwxArNK4aUyeNgsURSsloptJGXg9i3phQv +KUmi8wUG+7RP2qFsmmaf8EMJyupyj+sA1zU511YXRxcw9L6/P8JorzZAwan0qafoEGsIiveGHtya +KhUG9qPw9ODHFNRRf8+0222vR5YXm3dx2KdxnSQM9pQ/hTEST7ruToK4uT6PIzdezKKqdfcYbwnT +rqdUKDT74eA7YH2gvnmJhsifLfkKS8RQouf9eRbHegsYz85M733WB2+Y8a+xwXrXgTW4qhe04MsC +AwEAAaNCMEAwHQYDVR0OBBYEFCnFkKslrxHkYb+j/4hhkeYO/pyBMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAQDdr4Ouwo0RSVgrESLFF6QSU2TJ/s +Px+EnWVUXKgWAkD6bho3hO9ynYYKVZ1WKKxmLNA6VpM0ByWtCLCPyA8JWcqdmBzlVPi5RX9ql2+I +aE1KBiY3iAIOtsbWcpnOa3faYjGkVh+uX4132l32iPwa2Z61gfAyuOOI0JzzaqC5mxRZNTZPz/OO +Xl0XrRWV2N2y1RVuAE6zS89mlOTgzbUF2mNXi+WzqtvALhyQRNsaXRik7r4EW5nVcV9VZWRi1aKb +BFmGyGJ353yCRWo9F7/snXUMrqNvWtMvmDb08PUZqxFdyKbjKlhqQgnDvZImZjINXQhVdP+MmNAK +poRq0Tl9 +-----END CERTIFICATE----- + +D-TRUST Root Class 3 CA 2 2009 +============================== +-----BEGIN CERTIFICATE----- +MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQK +DAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTAe +Fw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NThaME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxE +LVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOAD +ER03UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42tSHKXzlA +BF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9RySPocq60vFYJfxLLHLGv +KZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsMlFqVlNpQmvH/pStmMaTJOKDfHR+4CS7z +p+hnUquVH+BGPtikw8paxTGA6Eian5Rp/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUC +AwEAAaOCARowggEWMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ +4PGEMA4GA1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVjdG9y +eS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUyMENBJTIwMiUyMDIw +MDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRlcmV2b2NhdGlvbmxpc3QwQ6BBoD+G +PWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAw +OS5jcmwwDQYJKoZIhvcNAQELBQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm +2H6NMLVwMeniacfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0 +o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4KzCUqNQT4YJEV +dT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8PIWmawomDeCTmGCufsYkl4ph +X5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3YJohw1+qRzT65ysCQblrGXnRl11z+o+I= +-----END CERTIFICATE----- + +D-TRUST Root Class 3 CA 2 EV 2009 +================================= +-----BEGIN CERTIFICATE----- +MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK +DAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw +OTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUwNDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK +DAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw +OTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfS +egpnljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM03TP1YtHh +zRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6ZqQTMFexgaDbtCHu39b+T +7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lRp75mpoo6Kr3HGrHhFPC+Oh25z1uxav60 +sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure35 +11H3a6UCAwEAAaOCASQwggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyv +cop9NteaHNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFwOi8v +ZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xhc3MlMjAzJTIwQ0El +MjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1ERT9jZXJ0aWZpY2F0ZXJldm9jYXRp +b25saXN0MEagRKBChkBodHRwOi8vd3d3LmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xh +c3NfM19jYV8yX2V2XzIwMDkuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+ +PPoeUSbrh/Yp3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05 +nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNFCSuGdXzfX2lX +ANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7naxpeG0ILD5EJt/rDiZE4OJudA +NCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqXKVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVv +w9y4AyHqnxbxLFS1 +-----END CERTIFICATE----- + +PSCProcert +========== +-----BEGIN CERTIFICATE----- +MIIJhjCCB26gAwIBAgIBCzANBgkqhkiG9w0BAQsFADCCAR4xPjA8BgNVBAMTNUF1dG9yaWRhZCBk +ZSBDZXJ0aWZpY2FjaW9uIFJhaXogZGVsIEVzdGFkbyBWZW5lem9sYW5vMQswCQYDVQQGEwJWRTEQ +MA4GA1UEBxMHQ2FyYWNhczEZMBcGA1UECBMQRGlzdHJpdG8gQ2FwaXRhbDE2MDQGA1UEChMtU2lz +dGVtYSBOYWNpb25hbCBkZSBDZXJ0aWZpY2FjaW9uIEVsZWN0cm9uaWNhMUMwQQYDVQQLEzpTdXBl +cmludGVuZGVuY2lhIGRlIFNlcnZpY2lvcyBkZSBDZXJ0aWZpY2FjaW9uIEVsZWN0cm9uaWNhMSUw +IwYJKoZIhvcNAQkBFhZhY3JhaXpAc3VzY2VydGUuZ29iLnZlMB4XDTEwMTIyODE2NTEwMFoXDTIw +MTIyNTIzNTk1OVowgdExJjAkBgkqhkiG9w0BCQEWF2NvbnRhY3RvQHByb2NlcnQubmV0LnZlMQ8w +DQYDVQQHEwZDaGFjYW8xEDAOBgNVBAgTB01pcmFuZGExKjAoBgNVBAsTIVByb3ZlZWRvciBkZSBD +ZXJ0aWZpY2Fkb3MgUFJPQ0VSVDE2MDQGA1UEChMtU2lzdGVtYSBOYWNpb25hbCBkZSBDZXJ0aWZp +Y2FjaW9uIEVsZWN0cm9uaWNhMQswCQYDVQQGEwJWRTETMBEGA1UEAxMKUFNDUHJvY2VydDCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANW39KOUM6FGqVVhSQ2oh3NekS1wwQYalNo97BVC +wfWMrmoX8Yqt/ICV6oNEolt6Vc5Pp6XVurgfoCfAUFM+jbnADrgV3NZs+J74BCXfgI8Qhd19L3uA +3VcAZCP4bsm+lU/hdezgfl6VzbHvvnpC2Mks0+saGiKLt38GieU89RLAu9MLmV+QfI4tL3czkkoh +RqipCKzx9hEC2ZUWno0vluYC3XXCFCpa1sl9JcLB/KpnheLsvtF8PPqv1W7/U0HU9TI4seJfxPmO +EO8GqQKJ/+MMbpfg353bIdD0PghpbNjU5Db4g7ayNo+c7zo3Fn2/omnXO1ty0K+qP1xmk6wKImG2 +0qCZyFSTXai20b1dCl53lKItwIKOvMoDKjSuc/HUtQy9vmebVOvh+qBa7Dh+PsHMosdEMXXqP+UH +0quhJZb25uSgXTcYOWEAM11G1ADEtMo88aKjPvM6/2kwLkDd9p+cJsmWN63nOaK/6mnbVSKVUyqU +td+tFjiBdWbjxywbk5yqjKPK2Ww8F22c3HxT4CAnQzb5EuE8XL1mv6JpIzi4mWCZDlZTOpx+FIyw +Bm/xhnaQr/2v/pDGj59/i5IjnOcVdo/Vi5QTcmn7K2FjiO/mpF7moxdqWEfLcU8UC17IAggmosvp +r2uKGcfLFFb14dq12fy/czja+eevbqQ34gcnAgMBAAGjggMXMIIDEzASBgNVHRMBAf8ECDAGAQH/ +AgEBMDcGA1UdEgQwMC6CD3N1c2NlcnRlLmdvYi52ZaAbBgVghl4CAqASDBBSSUYtRy0yMDAwNDAz +Ni0wMB0GA1UdDgQWBBRBDxk4qpl/Qguk1yeYVKIXTC1RVDCCAVAGA1UdIwSCAUcwggFDgBStuyId +xuDSAaj9dlBSk+2YwU2u06GCASakggEiMIIBHjE+MDwGA1UEAxM1QXV0b3JpZGFkIGRlIENlcnRp +ZmljYWNpb24gUmFpeiBkZWwgRXN0YWRvIFZlbmV6b2xhbm8xCzAJBgNVBAYTAlZFMRAwDgYDVQQH +EwdDYXJhY2FzMRkwFwYDVQQIExBEaXN0cml0byBDYXBpdGFsMTYwNAYDVQQKEy1TaXN0ZW1hIE5h +Y2lvbmFsIGRlIENlcnRpZmljYWNpb24gRWxlY3Ryb25pY2ExQzBBBgNVBAsTOlN1cGVyaW50ZW5k +ZW5jaWEgZGUgU2VydmljaW9zIGRlIENlcnRpZmljYWNpb24gRWxlY3Ryb25pY2ExJTAjBgkqhkiG +9w0BCQEWFmFjcmFpekBzdXNjZXJ0ZS5nb2IudmWCAQowDgYDVR0PAQH/BAQDAgEGME0GA1UdEQRG +MESCDnByb2NlcnQubmV0LnZloBUGBWCGXgIBoAwMClBTQy0wMDAwMDKgGwYFYIZeAgKgEgwQUklG +LUotMzE2MzUzNzMtNzB2BgNVHR8EbzBtMEagRKBChkBodHRwOi8vd3d3LnN1c2NlcnRlLmdvYi52 +ZS9sY3IvQ0VSVElGSUNBRE8tUkFJWi1TSEEzODRDUkxERVIuY3JsMCOgIaAfhh1sZGFwOi8vYWNy +YWl6LnN1c2NlcnRlLmdvYi52ZTA3BggrBgEFBQcBAQQrMCkwJwYIKwYBBQUHMAGGG2h0dHA6Ly9v +Y3NwLnN1c2NlcnRlLmdvYi52ZTBBBgNVHSAEOjA4MDYGBmCGXgMBAjAsMCoGCCsGAQUFBwIBFh5o +dHRwOi8vd3d3LnN1c2NlcnRlLmdvYi52ZS9kcGMwDQYJKoZIhvcNAQELBQADggIBACtZ6yKZu4Sq +T96QxtGGcSOeSwORR3C7wJJg7ODU523G0+1ng3dS1fLld6c2suNUvtm7CpsR72H0xpkzmfWvADmN +g7+mvTV+LFwxNG9s2/NkAZiqlCxB3RWGymspThbASfzXg0gTB1GEMVKIu4YXx2sviiCtxQuPcD4q +uxtxj7mkoP3YldmvWb8lK5jpY5MvYB7Eqvh39YtsL+1+LrVPQA3uvFd359m21D+VJzog1eWuq2w1 +n8GhHVnchIHuTQfiSLaeS5UtQbHh6N5+LwUeaO6/u5BlOsju6rEYNxxik6SgMexxbJHmpHmJWhSn +FFAFTKQAVzAswbVhltw+HoSvOULP5dAssSS830DD7X9jSr3hTxJkhpXzsOfIt+FTvZLm8wyWuevo +5pLtp4EJFAv8lXrPj9Y0TzYS3F7RNHXGRoAvlQSMx4bEqCaJqD8Zm4G7UaRKhqsLEQ+xrmNTbSjq +3TNWOByyrYDT13K9mmyZY+gAu0F2BbdbmRiKw7gSXFbPVgx96OLP7bx0R/vu0xdOIk9W/1DzLuY5 +poLWccret9W6aAjtmcz9opLLabid+Qqkpj5PkygqYWwHJgD/ll9ohri4zspV4KuxPX+Y1zMOWj3Y +eMLEYC/HYvBhkdI4sPaeVdtAgAUSM84dkpvRabP/v/GSCmE1P93+hvS84Bpxs2Km +-----END CERTIFICATE----- + +China Internet Network Information Center EV Certificates Root +============================================================== +-----BEGIN CERTIFICATE----- +MIID9zCCAt+gAwIBAgIESJ8AATANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMCQ04xMjAwBgNV +BAoMKUNoaW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24gQ2VudGVyMUcwRQYDVQQDDD5D +aGluYSBJbnRlcm5ldCBOZXR3b3JrIEluZm9ybWF0aW9uIENlbnRlciBFViBDZXJ0aWZpY2F0ZXMg +Um9vdDAeFw0xMDA4MzEwNzExMjVaFw0zMDA4MzEwNzExMjVaMIGKMQswCQYDVQQGEwJDTjEyMDAG +A1UECgwpQ2hpbmEgSW50ZXJuZXQgTmV0d29yayBJbmZvcm1hdGlvbiBDZW50ZXIxRzBFBgNVBAMM +PkNoaW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24gQ2VudGVyIEVWIENlcnRpZmljYXRl +cyBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm35z7r07eKpkQ0H1UN+U8i6y +jUqORlTSIRLIOTJCBumD1Z9S7eVnAztUwYyZmczpwA//DdmEEbK40ctb3B75aDFk4Zv6dOtouSCV +98YPjUesWgbdYavi7NifFy2cyjw1l1VxzUOFsUcW9SxTgHbP0wBkvUCZ3czY28Sf1hNfQYOL+Q2H +klY0bBoQCxfVWhyXWIQ8hBouXJE0bhlffxdpxWXvayHG1VA6v2G5BY3vbzQ6sm8UY78WO5upKv23 +KzhmBsUs4qpnHkWnjQRmQvaPK++IIGmPMowUc9orhpFjIpryp9vOiYurXccUwVswah+xt54ugQEC +7c+WXmPbqOY4twIDAQABo2MwYTAfBgNVHSMEGDAWgBR8cks5x8DbYqVPm6oYNJKiyoOCWTAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUfHJLOcfA22KlT5uqGDSSosqD +glkwDQYJKoZIhvcNAQEFBQADggEBACrDx0M3j92tpLIM7twUbY8opJhJywyA6vPtI2Z1fcXTIWd5 +0XPFtQO3WKwMVC/GVhMPMdoG52U7HW8228gd+f2ABsqjPWYWqJ1MFn3AlUa1UeTiH9fqBk1jjZaM +7+czV0I664zBechNdn3e9rG3geCg+aF4RhcaVpjwTj2rHO3sOdwHSPdj/gauwqRcalsyiMXHM4Ws +ZkJHwlgkmeHlPuV1LI5D1l08eB6olYIpUNHRFrrvwb562bTYzB5MRuF3sTGrvSrIzo9uoV1/A3U0 +5K2JRVRevq4opbs/eHnrc7MKDf2+yfdWrPa37S+bISnHOLaVxATywy39FCqQmbkHzJ8= +-----END CERTIFICATE----- + +Swisscom Root CA 2 +================== +-----BEGIN CERTIFICATE----- +MIIF2TCCA8GgAwIBAgIQHp4o6Ejy5e/DfEoeWhhntjANBgkqhkiG9w0BAQsFADBkMQswCQYDVQQG +EwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0YWwgQ2VydGlmaWNhdGUgU2Vy +dmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3QgQ0EgMjAeFw0xMTA2MjQwODM4MTRaFw0zMTA2 +MjUwNzM4MTRaMGQxCzAJBgNVBAYTAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGln +aXRhbCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAyMIIC +IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAlUJOhJ1R5tMJ6HJaI2nbeHCOFvErjw0DzpPM +LgAIe6szjPTpQOYXTKueuEcUMncy3SgM3hhLX3af+Dk7/E6J2HzFZ++r0rk0X2s682Q2zsKwzxNo +ysjL67XiPS4h3+os1OD5cJZM/2pYmLcX5BtS5X4HAB1f2uY+lQS3aYg5oUFgJWFLlTloYhyxCwWJ +wDaCFCE/rtuh/bxvHGCGtlOUSbkrRsVPACu/obvLP+DHVxxX6NZp+MEkUp2IVd3Chy50I9AU/SpH +Wrumnf2U5NGKpV+GY3aFy6//SSj8gO1MedK75MDvAe5QQQg1I3ArqRa0jG6F6bYRzzHdUyYb3y1a +SgJA/MTAtukxGggo5WDDH8SQjhBiYEQN7Aq+VRhxLKX0srwVYv8c474d2h5Xszx+zYIdkeNL6yxS +NLCK/RJOlrDrcH+eOfdmQrGrrFLadkBXeyq96G4DsguAhYidDMfCd7Camlf0uPoTXGiTOmekl9Ab +mbeGMktg2M7v0Ax/lZ9vh0+Hio5fCHyqW/xavqGRn1V9TrALacywlKinh/LTSlDcX3KwFnUey7QY +Ypqwpzmqm59m2I2mbJYV4+by+PGDYmy7Velhk6M99bFXi08jsJvllGov34zflVEpYKELKeRcVVi3 +qPyZ7iVNTA6z00yPhOgpD/0QVAKFyPnlw4vP5w8CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYw +HQYDVR0hBBYwFDASBgdghXQBUwIBBgdghXQBUwIBMBIGA1UdEwEB/wQIMAYBAf8CAQcwHQYDVR0O +BBYEFE0mICKJS9PVpAqhb97iEoHF8TwuMB8GA1UdIwQYMBaAFE0mICKJS9PVpAqhb97iEoHF8Twu +MA0GCSqGSIb3DQEBCwUAA4ICAQAyCrKkG8t9voJXiblqf/P0wS4RfbgZPnm3qKhyN2abGu2sEzsO +v2LwnN+ee6FTSA5BesogpxcbtnjsQJHzQq0Qw1zv/2BZf82Fo4s9SBwlAjxnffUy6S8w5X2lejjQ +82YqZh6NM4OKb3xuqFp1mrjX2lhIREeoTPpMSQpKwhI3qEAMw8jh0FcNlzKVxzqfl9NX+Ave5XLz +o9v/tdhZsnPdTSpxsrpJ9csc1fV5yJmz/MFMdOO0vSk3FQQoHt5FRnDsr7p4DooqzgB53MBfGWcs +a0vvaGgLQ+OswWIJ76bdZWGgr4RVSJFSHMYlkSrQwSIjYVmvRRGFHQEkNI/Ps/8XciATwoCqISxx +OQ7Qj1zB09GOInJGTB2Wrk9xseEFKZZZ9LuedT3PDTcNYtsmjGOpI99nBjx8Oto0QuFmtEYE3saW +mA9LSHokMnWRn6z3aOkquVVlzl1h0ydw2Df+n7mvoC5Wt6NlUe07qxS/TFED6F+KBZvuim6c779o ++sjaC+NCydAXFJy3SuCvkychVSa1ZC+N8f+mQAWFBVzKBxlcCxMoTFh/wqXvRdpg065lYZ1Tg3TC +rvJcwhbtkj6EPnNgiLx29CzP0H1907he0ZESEOnN3col49XtmS++dYFLJPlFRpTJKSFTnCZFqhMX +5OfNeOI5wSsSnqaeG8XmDtkx2Q== +-----END CERTIFICATE----- + +Swisscom Root EV CA 2 +===================== +-----BEGIN CERTIFICATE----- +MIIF4DCCA8igAwIBAgIRAPL6ZOJ0Y9ON/RAdBB92ylgwDQYJKoZIhvcNAQELBQAwZzELMAkGA1UE +BhMCY2gxETAPBgNVBAoTCFN3aXNzY29tMSUwIwYDVQQLExxEaWdpdGFsIENlcnRpZmljYXRlIFNl +cnZpY2VzMR4wHAYDVQQDExVTd2lzc2NvbSBSb290IEVWIENBIDIwHhcNMTEwNjI0MDk0NTA4WhcN +MzEwNjI1MDg0NTA4WjBnMQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsT +HERpZ2l0YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxHjAcBgNVBAMTFVN3aXNzY29tIFJvb3QgRVYg +Q0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMT3HS9X6lds93BdY7BxUglgRCgz +o3pOCvrY6myLURYaVa5UJsTMRQdBTxB5f3HSek4/OE6zAMaVylvNwSqD1ycfMQ4jFrclyxy0uYAy +Xhqdk/HoPGAsp15XGVhRXrwsVgu42O+LgrQ8uMIkqBPHoCE2G3pXKSinLr9xJZDzRINpUKTk4Rti +GZQJo/PDvO/0vezbE53PnUgJUmfANykRHvvSEaeFGHR55E+FFOtSN+KxRdjMDUN/rhPSays/p8Li +qG12W0OfvrSdsyaGOx9/5fLoZigWJdBLlzin5M8J0TbDC77aO0RYjb7xnglrPvMyxyuHxuxenPaH +Za0zKcQvidm5y8kDnftslFGXEBuGCxobP/YCfnvUxVFkKJ3106yDgYjTdLRZncHrYTNaRdHLOdAG +alNgHa/2+2m8atwBz735j9m9W8E6X47aD0upm50qKGsaCnw8qyIL5XctcfaCNYGu+HuB5ur+rPQa +m3Rc6I8k9l2dRsQs0h4rIWqDJ2dVSqTjyDKXZpBy2uPUZC5f46Fq9mDU5zXNysRojddxyNMkM3Ox +bPlq4SjbX8Y96L5V5jcb7STZDxmPX2MYWFCBUWVv8p9+agTnNCRxunZLWB4ZvRVgRaoMEkABnRDi +xzgHcgplwLa7JSnaFp6LNYth7eVxV4O1PHGf40+/fh6Bn0GXAgMBAAGjgYYwgYMwDgYDVR0PAQH/ +BAQDAgGGMB0GA1UdIQQWMBQwEgYHYIV0AVMCAgYHYIV0AVMCAjASBgNVHRMBAf8ECDAGAQH/AgED +MB0GA1UdDgQWBBRF2aWBbj2ITY1x0kbBbkUe88SAnTAfBgNVHSMEGDAWgBRF2aWBbj2ITY1x0kbB +bkUe88SAnTANBgkqhkiG9w0BAQsFAAOCAgEAlDpzBp9SSzBc1P6xXCX5145v9Ydkn+0UjrgEjihL +j6p7jjm02Vj2e6E1CqGdivdj5eu9OYLU43otb98TPLr+flaYC/NUn81ETm484T4VvwYmneTwkLbU +wp4wLh/vx3rEUMfqe9pQy3omywC0Wqu1kx+AiYQElY2NfwmTv9SoqORjbdlk5LgpWgi/UOGED1V7 +XwgiG/W9mR4U9s70WBCCswo9GcG/W6uqmdjyMb3lOGbcWAXH7WMaLgqXfIeTK7KK4/HsGOV1timH +59yLGn602MnTihdsfSlEvoqq9X46Lmgxk7lq2prg2+kupYTNHAq4Sgj5nPFhJpiTt3tm7JFe3VE/ +23MPrQRYCd0EApUKPtN236YQHoA96M2kZNEzx5LH4k5E4wnJTsJdhw4Snr8PyQUQ3nqjsTzyP6Wq +J3mtMX0f/fwZacXduT98zca0wjAefm6S139hdlqP65VNvBFuIXxZN5nQBrz5Bm0yFqXZaajh3DyA +HmBR3NdUIR7KYndP+tiPsys6DXhyyWhBWkdKwqPrGtcKqzwyVcgKEZzfdNbwQBUdyLmPtTbFr/gi +uMod89a2GQ+fYWVq6nTIfI/DT11lgh/ZDYnadXL77/FHZxOzyNEZiCcmmpl5fx7kLD977vHeTYuW +l8PVP3wbI+2ksx0WckNLIOFZfsLorSa/ovc= +-----END CERTIFICATE----- + +CA Disig Root R1 +================ +-----BEGIN CERTIFICATE----- +MIIFaTCCA1GgAwIBAgIJAMMDmu5QkG4oMA0GCSqGSIb3DQEBBQUAMFIxCzAJBgNVBAYTAlNLMRMw +EQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMuMRkwFwYDVQQDExBDQSBEaXNp +ZyBSb290IFIxMB4XDTEyMDcxOTA5MDY1NloXDTQyMDcxOTA5MDY1NlowUjELMAkGA1UEBhMCU0sx +EzARBgNVBAcTCkJyYXRpc2xhdmExEzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERp +c2lnIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCqw3j33Jijp1pedxiy +3QRkD2P9m5YJgNXoqqXinCaUOuiZc4yd39ffg/N4T0Dhf9Kn0uXKE5Pn7cZ3Xza1lK/oOI7bm+V8 +u8yN63Vz4STN5qctGS7Y1oprFOsIYgrY3LMATcMjfF9DCCMyEtztDK3AfQ+lekLZWnDZv6fXARz2 +m6uOt0qGeKAeVjGu74IKgEH3G8muqzIm1Cxr7X1r5OJeIgpFy4QxTaz+29FHuvlglzmxZcfe+5nk +CiKxLU3lSCZpq+Kq8/v8kiky6bM+TR8noc2OuRf7JT7JbvN32g0S9l3HuzYQ1VTW8+DiR0jm3hTa +YVKvJrT1cU/J19IG32PK/yHoWQbgCNWEFVP3Q+V8xaCJmGtzxmjOZd69fwX3se72V6FglcXM6pM6 +vpmumwKjrckWtc7dXpl4fho5frLABaTAgqWjR56M6ly2vGfb5ipN0gTco65F97yLnByn1tUD3AjL +LhbKXEAz6GfDLuemROoRRRw1ZS0eRWEkG4IupZ0zXWX4Qfkuy5Q/H6MMMSRE7cderVC6xkGbrPAX +ZcD4XW9boAo0PO7X6oifmPmvTiT6l7Jkdtqr9O3jw2Dv1fkCyC2fg69naQanMVXVz0tv/wQFx1is +XxYb5dKj6zHbHzMVTdDypVP1y+E9Tmgt2BLdqvLmTZtJ5cUoobqwWsagtQIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUiQq0OJMa5qvum5EY+fU8PjXQ +04IwDQYJKoZIhvcNAQEFBQADggIBADKL9p1Kyb4U5YysOMo6CdQbzoaz3evUuii+Eq5FLAR0rBNR +xVgYZk2C2tXck8An4b58n1KeElb21Zyp9HWc+jcSjxyT7Ff+Bw+r1RL3D65hXlaASfX8MPWbTx9B +LxyE04nH4toCdu0Jz2zBuByDHBb6lM19oMgY0sidbvW9adRtPTXoHqJPYNcHKfyyo6SdbhWSVhlM +CrDpfNIZTUJG7L399ldb3Zh+pE3McgODWF3vkzpBemOqfDqo9ayk0d2iLbYq/J8BjuIQscTK5Gfb +VSUZP/3oNn6z4eGBrxEWi1CXYBmCAMBrTXO40RMHPuq2MU/wQppt4hF05ZSsjYSVPCGvxdpHyN85 +YmLLW1AL14FABZyb7bq2ix4Eb5YgOe2kfSnbSM6C3NQCjR0EMVrHS/BsYVLXtFHCgWzN4funodKS +ds+xDzdYpPJScWc/DIh4gInByLUfkmO+p3qKViwaqKactV2zY9ATIKHrkWzQjX2v3wvkF7mGnjix +lAxYjOBVqjtjbZqJYLhkKpLGN/R+Q0O3c+gB53+XD9fyexn9GtePyfqFa3qdnom2piiZk4hA9z7N +UaPK6u95RyG1/jLix8NRb76AdPCkwzryT+lf3xkK8jsTQ6wxpLPn6/wY1gGp8yqPNg7rtLG8t0zJ +a7+h89n07eLw4+1knj0vllJPgFOL +-----END CERTIFICATE----- + +CA Disig Root R2 +================ +-----BEGIN CERTIFICATE----- +MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNVBAYTAlNLMRMw +EQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMuMRkwFwYDVQQDExBDQSBEaXNp +ZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQyMDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sx +EzARBgNVBAcTCkJyYXRpc2xhdmExEzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERp +c2lnIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbC +w3OeNcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNHPWSb6Wia +xswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3Ix2ymrdMxp7zo5eFm1tL7 +A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbeQTg06ov80egEFGEtQX6sx3dOy1FU+16S +GBsEWmjGycT6txOgmLcRK7fWV8x8nhfRyyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqV +g8NTEQxzHQuyRpDRQjrOQG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa +5Beny912H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJQfYE +koopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUDi/ZnWejBBhG93c+A +Ak9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORsnLMOPReisjQS1n6yqEm70XooQL6i +Fh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5u +Qu0wDQYJKoZIhvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM +tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqfGopTpti72TVV +sRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkblvdhuDvEK7Z4bLQjb/D907Je +dR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka+elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W8 +1k/BfDxujRNt+3vrMNDcTa/F1balTFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjx +mHHEt38OFdAlab0inSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01 +utI3gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18DrG5gPcFw0 +sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3OszMOl6W8KjptlwlCFtaOg +UxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8xL4ysEr3vQCj8KWefshNPZiTEUxnpHikV +7+ZtsH8tZ/3zbBt1RqPlShfppNcL +-----END CERTIFICATE----- + +ACCVRAIZ1 +========= +-----BEGIN CERTIFICATE----- +MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UEAwwJQUNDVlJB +SVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQswCQYDVQQGEwJFUzAeFw0xMTA1 +MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQBgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwH +UEtJQUNDVjENMAsGA1UECgwEQUNDVjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQCbqau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gM +jmoYHtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWoG2ioPej0 +RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpAlHPrzg5XPAOBOp0KoVdD +aaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhrIA8wKFSVf+DuzgpmndFALW4ir50awQUZ +0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDG +WuzndN9wrqODJerWx5eHk6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs7 +8yM2x/474KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMOm3WR +5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpacXpkatcnYGMN285J +9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPluUsXQA+xtrn13k/c4LOsOxFwYIRK +Q26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYIKwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRw +Oi8vd3d3LmFjY3YuZXMvZmlsZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEu +Y3J0MB8GCCsGAQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2 +VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeTVfZW6oHlNsyM +Hj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIGCCsGAQUFBwICMIIBFB6CARAA +QQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUAcgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBh +AO0AegAgAGQAZQAgAGwAYQAgAEEAQwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUA +YwBuAG8AbABvAGcA7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBj +AHQAcgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAAQwBQAFMA +IABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUAczAwBggrBgEFBQcCARYk +aHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2MuaHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0 +dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRtaW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2 +MV9kZXIuY3JsMA4GA1UdDwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZI +hvcNAQEFBQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdpD70E +R9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gUJyCpZET/LtZ1qmxN +YEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+mAM/EKXMRNt6GGT6d7hmKG9Ww7Y49 +nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepDvV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJ +TS+xJlsndQAJxGJ3KQhfnlmstn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3 +sCPdK6jT2iWH7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h +I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szAh1xA2syVP1Xg +Nce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xFd3+YJ5oyXSrjhO7FmGYvliAd +3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2HpPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3p +EfbRD0tVNEYqi4Y7 +-----END CERTIFICATE----- + +TWCA Global Root CA +=================== +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcxEjAQBgNVBAoT +CVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMTVFdDQSBHbG9iYWwgUm9vdCBD +QTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQK +EwlUQUlXQU4tQ0ExEDAOBgNVBAsTB1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3Qg +Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2C +nJfF10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz0ALfUPZV +r2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfChMBwqoJimFb3u/Rk28OKR +Q4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbHzIh1HrtsBv+baz4X7GGqcXzGHaL3SekV +tTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1W +KKD+u4ZqyPpcC1jcxkt2yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99 +sy2sbZCilaLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYPoA/p +yJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQABDzfuBSO6N+pjWxn +kjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcEqYSjMq+u7msXi7Kx/mzhkIyIqJdI +zshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMC +AQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6g +cFGn90xHNcgL1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn +LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WFH6vPNOw/KP4M +8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNoRI2T9GRwoD2dKAXDOXC4Ynsg +/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlg +lPx4mI88k1HtQJAH32RjJMtOcQWh15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryP +A9gK8kxkRr05YuWW6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3m +i4TWnsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5jwa19hAM8 +EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWzaGHQRiapIVJpLesux+t3 +zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmyKwbQBM0= +-----END CERTIFICATE----- + +TeliaSonera Root CA v1 +====================== +-----BEGIN CERTIFICATE----- +MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAwNzEUMBIGA1UE +CgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJvb3QgQ0EgdjEwHhcNMDcxMDE4 +MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYDVQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwW +VGVsaWFTb25lcmEgUm9vdCBDQSB2MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+ +6yfwIaPzaSZVfp3FVRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA +3GV17CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+XZ75Ljo1k +B1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+/jXh7VB7qTCNGdMJjmhn +Xb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxH +oLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkmdtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3 +F0fUTPHSiXk+TT2YqGHeOh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJ +oWjiUIMusDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4pgd7 +gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fsslESl1MpWtTwEhDc +TwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQarMCpgKIv7NHfirZ1fpoeDVNAgMB +AAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qW +DNXr+nuqF+gTEjANBgkqhkiG9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNm +zqjMDfz1mgbldxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx +0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1TjTQpgcmLNkQfW +pb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBedY2gea+zDTYa4EzAvXUYNR0PV +G6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpc +c41teyWRyu5FrgZLAMzTsVlQ2jqIOylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOT +JsjrDNYmiLbAJM+7vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2 +qReWt88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcnHL/EVlP6 +Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVxSK236thZiNSQvxaz2ems +WWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= +-----END CERTIFICATE----- + +E-Tugra Certification Authority +=============================== +-----BEGIN CERTIFICATE----- +MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNVBAYTAlRSMQ8w +DQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamls +ZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN +ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMw +NTEyMDk0OFoXDTIzMDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmEx +QDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxl +cmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQD +DB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEA4vU/kwVRHoViVF56C/UYB4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vd +hQd2h8y/L5VMzH2nPbxHD5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5K +CKpbknSFQ9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEoq1+g +ElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3Dk14opz8n8Y4e0ypQ +BaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcHfC425lAcP9tDJMW/hkd5s3kc91r0 +E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsutdEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gz +rt48Ue7LE3wBf4QOXVGUnhMMti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAq +jqFGOjGY5RH8zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn +rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUXU8u3Zg5mTPj5 +dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6Jyr+zE7S6E5UMA8GA1UdEwEB +/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEG +MA0GCSqGSIb3DQEBCwUAA4ICAQAFNzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAK +kEh47U6YA5n+KGCRHTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jO +XKqYGwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c77NCR807 +VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3+GbHeJAAFS6LrVE1Uweo +a2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WKvJUawSg5TB9D0pH0clmKuVb8P7Sd2nCc +dlqMQ1DujjByTd//SffGqWfZbawCEeI6FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEV +KV0jq9BgoRJP3vQXzTLlyb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gT +Dx4JnW2PAJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpDy4Q0 +8ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8dNL/+I5c30jn6PQ0G +C7TbO6Orb1wdtn7os4I07QZcJA== +-----END CERTIFICATE----- + +T-TeleSec GlobalRoot Class 2 +============================ +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM +IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU +cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgx +MDAxMTA0MDE0WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz +dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD +ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUdAqSzm1nzHoqvNK38DcLZ +SBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiCFoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/F +vudocP05l03Sx5iRUKrERLMjfTlH6VJi1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx970 +2cu+fjOlbpSD8DT6IavqjnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGV +WOHAD3bZwI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGjQjBA +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/WSA2AHmgoCJrjNXy +YdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhyNsZt+U2e+iKo4YFWz827n+qrkRk4 +r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPACuvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNf +vNoBYimipidx5joifsFvHZVwIEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR +3p1m0IvVVGb6g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN +9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlPBSeOE6Fuwg== +-----END CERTIFICATE----- + +Atos TrustedRoot 2011 +===================== +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UEAwwVQXRvcyBU +cnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0xMTA3MDcxNDU4 +MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMMFUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsG +A1UECgwEQXRvczELMAkGA1UEBhMCREUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCV +hTuXbyo7LjvPpvMpNb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr +54rMVD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+SZFhyBH+ +DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ4J7sVaE3IqKHBAUsR320 +HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0Lcp2AMBYHlT8oDv3FdU9T1nSatCQujgKR +z3bFmx5VdJx4IbHwLfELn8LVlhgf8FQieowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7R +l+lwrrw7GWzbITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZ +bNshMBgGA1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB +CwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8jvZfza1zv7v1Apt+h +k6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kPDpFrdRbhIfzYJsdHt6bPWHJxfrrh +TZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pcmaHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a9 +61qn8FYiqTxlVMYVqL2Gns2Dlmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G +3mB/ufNPRJLvKrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed +-----END CERTIFICATE----- + +QuoVadis Root CA 1 G3 +===================== +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQELBQAwSDELMAkG +A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv +b3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJN +MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEg +RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakE +PBtVwedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWerNrwU8lm +PNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF34168Xfuw6cwI2H44g4hWf6 +Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh4Pw5qlPafX7PGglTvF0FBM+hSo+LdoIN +ofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXpUhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/l +g6AnhF4EwfWQvTA9xO+oabw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV +7qJZjqlc3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/GKubX +9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSthfbZxbGL0eUQMk1f +iyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KOTk0k+17kBL5yG6YnLUlamXrXXAkg +t3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOtzCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZI +hvcNAQELBQADggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC +MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2cDMT/uFPpiN3 +GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUNqXsCHKnQO18LwIE6PWThv6ct +Tr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP ++V04ikkwj+3x6xn0dxoxGE1nVGwvb2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh +3jRJjehZrJ3ydlo28hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fa +wx/kNSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNjZgKAvQU6 +O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhpq1467HxpvMc7hU6eFbm0 +FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFtnh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOV +hMJKzRwuJIczYOXD +-----END CERTIFICATE----- + +QuoVadis Root CA 2 G3 +===================== +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQELBQAwSDELMAkG +A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv +b3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJN +MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIg +RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFh +ZiFfqq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMWn4rjyduY +NM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ymc5GQYaYDFCDy54ejiK2t +oIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+O7q414AB+6XrW7PFXmAqMaCvN+ggOp+o +MiwMzAkd056OXbxMmO7FGmh77FOm6RQ1o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+l +V0POKa2Mq1W/xPtbAd0jIaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZo +L1NesNKqIcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz8eQQ +sSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43ehvNURG3YBZwjgQQvD +6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l7ZizlWNof/k19N+IxWA1ksB8aRxh +lRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALGcC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZI +hvcNAQELBQADggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 +AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RCroijQ1h5fq7K +pVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0GaW/ZZGYjeVYg3UQt4XAoeo0L9 +x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4nlv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgz +dWqTHBLmYF5vHX/JHyPLhGGfHoJE+V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6X +U/IyAgkwo1jwDQHVcsaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+Nw +mNtddbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNgKCLjsZWD +zYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeMHVOyToV7BjjHLPj4sHKN +JeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4WSr2Rz0ZiC3oheGe7IUIarFsNMkd7Egr +O3jtZsSOeWmD3n+M +-----END CERTIFICATE----- + +QuoVadis Root CA 3 G3 +===================== +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQELBQAwSDELMAkG +A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv +b3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJN +MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMg +RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286 +IxSR/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNuFoM7pmRL +Mon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXRU7Ox7sWTaYI+FrUoRqHe +6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+cra1AdHkrAj80//ogaX3T7mH1urPnMNA3 +I4ZyYUUpSFlob3emLoG+B01vr87ERRORFHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3U +VDmrJqMz6nWB2i3ND0/kA9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f7 +5li59wzweyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634RylsSqi +Md5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBpVzgeAVuNVejH38DM +dyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0QA4XN8f+MFrXBsj6IbGB/kE+V9/Yt +rQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZI +hvcNAQELBQADggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px +KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnIFUBhynLWcKzS +t/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5WvvoxXqA/4Ti2Tk08HS6IT7SdEQ +TXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFgu/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9Du +DcpmvJRPpq3t/O5jrFc/ZSXPsoaP0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGib +Ih6BJpsQBJFxwAYf3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmD +hPbl8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+DhcI00iX +0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HNPlopNLk9hM6xZdRZkZFW +dSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ywaZWWDYWGWVjUTR939+J399roD1B0y2 +PpxxVJkES/1Y+Zj0 +-----END CERTIFICATE----- + +DigiCert Assured ID Root G2 +=========================== +-----BEGIN CERTIFICATE----- +MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw +IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgw +MTE1MTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL +ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSAn61UQbVH +35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4HteccbiJVMWWXvdMX0h5i89vq +bFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9HpEgjAALAcKxHad3A2m67OeYfcgnDmCXRw +VWmvo2ifv922ebPynXApVfSr/5Vh88lAbx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OP +YLfykqGxvYmJHzDNw6YuYjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+Rn +lTGNAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTO +w0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPIQW5pJ6d1Ee88hjZv +0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I0jJmwYrA8y8678Dj1JGG0VDjA9tz +d29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4GnilmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAW +hsI6yLETcDbYz+70CjTVW0z9B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0M +jomZmWzwPDCvON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo +IhNzbM8m9Yop5w== +-----END CERTIFICATE----- + +DigiCert Assured ID Root G3 +=========================== +-----BEGIN CERTIFICATE----- +MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYD +VQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1 +MTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQ +BgcqhkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJfZn4f5dwb +RXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17QRSAPWXYQ1qAk8C3eNvJs +KTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgF +UaFNN6KDec6NHSrkhDAKBggqhkjOPQQDAwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5Fy +YZ5eEJJZVrmDxxDnOOlYJjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy +1vUhZscv6pZjamVFkpUBtA== +-----END CERTIFICATE----- + +DigiCert Global Root G2 +======================= +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw +HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUx +MjAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 +dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI2/Ou8jqJ +kTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx1x7e/dfgy5SDN67sH0NO +3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQq2EGnI/yuum06ZIya7XzV+hdG82MHauV +BJVJ8zUtluNJbd134/tJS7SsVQepj5WztCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyM +UNGPHgm+F6HmIcr9g+UQvIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQAB +o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV5uNu +5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY1Yl9PMWLSn/pvtsr +F9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4NeF22d+mQrvHRAiGfzZ0JFrabA0U +WTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NGFdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBH +QRFXGU7Aj64GxJUTFy8bJZ918rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/ +iyK5S9kJRaTepLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= +-----END CERTIFICATE----- + +DigiCert Global Root G3 +======================= +-----BEGIN CERTIFICATE----- +MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAwHgYD +VQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAw +MDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k +aWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0C +AQYFK4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FGfp4tn+6O +YwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPOZ9wj/wMco+I+o0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNp +Yim8S8YwCgYIKoZIzj0EAwMDaAAwZQIxAK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y +3maTD/HMsQmP3Wyr+mt/oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34 +VOKa5Vt8sycX +-----END CERTIFICATE----- + +DigiCert Trusted Root G4 +======================== +-----BEGIN CERTIFICATE----- +MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBiMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEw +HwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1 +MTIwMDAwWjBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0G +CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3yithZwuEp +pz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1Ifxp4VpX6+n6lXFllVcq9o +k3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDVySAdYyktzuxeTsiT+CFhmzTrBcZe7Fsa +vOvJz82sNEBfsXpm7nfISKhmV1efVFiODCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGY +QJB5w3jHtrHEtWoYOAMQjdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6 +MUSaM0C/CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCiEhtm +mnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADMfRyVw4/3IbKyEbe7 +f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QYuKZ3AeEPlAwhHbJUKSWJbOUOUlFH +dL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXKchYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8 +oR7FwI+isX4KJpn15GkvmB0t9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud +DwEB/wQEAwIBhjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD +ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2SV1EY+CtnJYY +ZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd+SeuMIW59mdNOj6PWTkiU0Tr +yF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWcfFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy +7zBZLq7gcfJW5GqXb5JQbZaNaHqasjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iah +ixTXTBmyUEFxPT9NcCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN +5r5N0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie4u1Ki7wb +/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mIr/OSmbaz5mEP0oUA51Aa +5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tK +G48BtieVU+i2iW1bvGjUI+iLUaJW+fCmgKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP +82Z+ +-----END CERTIFICATE----- + +WoSign +====== +-----BEGIN CERTIFICATE----- +MIIFdjCCA16gAwIBAgIQXmjWEXGUY1BWAGjzPsnFkTANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQG +EwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxKjAoBgNVBAMTIUNlcnRpZmljYXRpb24g +QXV0aG9yaXR5IG9mIFdvU2lnbjAeFw0wOTA4MDgwMTAwMDFaFw0zOTA4MDgwMTAwMDFaMFUxCzAJ +BgNVBAYTAkNOMRowGAYDVQQKExFXb1NpZ24gQ0EgTGltaXRlZDEqMCgGA1UEAxMhQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkgb2YgV29TaWduMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA +vcqNrLiRFVaXe2tcesLea9mhsMMQI/qnobLMMfo+2aYpbxY94Gv4uEBf2zmoAHqLoE1UfcIiePyO +CbiohdfMlZdLdNiefvAA5A6JrkkoRBoQmTIPJYhTpA2zDxIIFgsDcSccf+Hb0v1naMQFXQoOXXDX +2JegvFNBmpGN9J42Znp+VsGQX+axaCA2pIwkLCxHC1l2ZjC1vt7tj/id07sBMOby8w7gLJKA84X5 +KIq0VC6a7fd2/BVoFutKbOsuEo/Uz/4Mx1wdC34FMr5esAkqQtXJTpCzWQ27en7N1QhatH/YHGkR ++ScPewavVIMYe+HdVHpRaG53/Ma/UkpmRqGyZxq7o093oL5d//xWC0Nyd5DKnvnyOfUNqfTq1+ez +EC8wQjchzDBwyYaYD8xYTYO7feUapTeNtqwylwA6Y3EkHp43xP901DfA4v6IRmAR3Qg/UDaruHqk +lWJqbrDKaiFaafPz+x1wOZXzp26mgYmhiMU7ccqjUu6Du/2gd/Tkb+dC221KmYo0SLwX3OSACCK2 +8jHAPwQ+658geda4BmRkAjHXqc1S+4RFaQkAKtxVi8QGRkvASh0JWzko/amrzgD5LkhLJuYwTKVY +yrREgk/nkR4zw7CT/xH8gdLKH3Ep3XZPkiWvHYG3Dy+MwwbMLyejSuQOmbp8HkUff6oZRZb9/D0C +AwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFOFmzw7R +8bNLtwYgFP6HEtX2/vs+MA0GCSqGSIb3DQEBBQUAA4ICAQCoy3JAsnbBfnv8rWTjMnvMPLZdRtP1 +LOJwXcgu2AZ9mNELIaCJWSQBnfmvCX0KI4I01fx8cpm5o9dU9OpScA7F9dY74ToJMuYhOZO9sxXq +T2r09Ys/L3yNWC7F4TmgPsc9SnOeQHrAK2GpZ8nzJLmzbVUsWh2eJXLOC62qx1ViC777Y7NhRCOj +y+EaDveaBk3e1CNOIZZbOVtXHS9dCF4Jef98l7VNg64N1uajeeAz0JmWAjCnPv/So0M/BVoG6kQC +2nz4SNAzqfkHx5Xh9T71XXG68pWpdIhhWeO/yloTunK0jF02h+mmxTwTv97QRCbut+wucPrXnbes +5cVAWubXbHssw1abR80LzvobtCHXt2a49CUwi1wNuepnsvRtrtWhnk/Yn+knArAdBtaP4/tIEp9/ +EaEQPkxROpaw0RPxx9gmrjrKkcRpnd8BKWRRb2jaFOwIQZeQjdCygPLPwj2/kWjFgGcexGATVdVh +mVd8upUPYUk6ynW8yQqTP2cOEvIo4jEbwFcW3wh8GcF+Dx+FHgo2fFt+J7x6v+Db9NpSvd4MVHAx +kUOVyLzwPt0JfjBkUO1/AaQzZ01oT74V77D2AhGiGxMlOtzCWfHjXEa7ZywCRuoeSKbmW9m1vFGi +kpbbqsY3Iqb+zCB0oy2pLmvLwIIRIbWTee5Ehr7XHuQe+w== +-----END CERTIFICATE----- + +WoSign China +============ +-----BEGIN CERTIFICATE----- +MIIFWDCCA0CgAwIBAgIQUHBrzdgT/BtOOzNy0hFIjTANBgkqhkiG9w0BAQsFADBGMQswCQYDVQQG +EwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxGzAZBgNVBAMMEkNBIOayg+mAmuagueiv +geS5pjAeFw0wOTA4MDgwMTAwMDFaFw0zOTA4MDgwMTAwMDFaMEYxCzAJBgNVBAYTAkNOMRowGAYD +VQQKExFXb1NpZ24gQ0EgTGltaXRlZDEbMBkGA1UEAwwSQ0Eg5rKD6YCa5qC56K+B5LmmMIICIjAN +BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0EkhHiX8h8EqwqzbdoYGTufQdDTc7WU1/FDWiD+k +8H/rD195L4mx/bxjWDeTmzj4t1up+thxx7S8gJeNbEvxUNUqKaqoGXqW5pWOdO2XCld19AXbbQs5 +uQF/qvbW2mzmBeCkTVL829B0txGMe41P/4eDrv8FAxNXUDf+jJZSEExfv5RxadmWPgxDT74wwJ85 +dE8GRV2j1lY5aAfMh09Qd5Nx2UQIsYo06Yms25tO4dnkUkWMLhQfkWsZHWgpLFbE4h4TV2TwYeO5 +Ed+w4VegG63XX9Gv2ystP9Bojg/qnw+LNVgbExz03jWhCl3W6t8Sb8D7aQdGctyB9gQjF+BNdeFy +b7Ao65vh4YOhn0pdr8yb+gIgthhid5E7o9Vlrdx8kHccREGkSovrlXLp9glk3Kgtn3R46MGiCWOc +76DbT52VqyBPt7D3h1ymoOQ3OMdc4zUPLK2jgKLsLl3Az+2LBcLmc272idX10kaO6m1jGx6KyX2m ++Jzr5dVjhU1zZmkR/sgO9MHHZklTfuQZa/HpelmjbX7FF+Ynxu8b22/8DU0GAbQOXDBGVWCvOGU6 +yke6rCzMRh+yRpY/8+0mBe53oWprfi1tWFxK1I5nuPHa1UaKJ/kR8slC/k7e3x9cxKSGhxYzoacX +GKUN5AXlK8IrC6KVkLn9YDxOiT7nnO4fuwECAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1Ud +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFOBNv9ybQV0T6GTwp+kVpOGBwboxMA0GCSqGSIb3DQEBCwUA +A4ICAQBqinA4WbbaixjIvirTthnVZil6Xc1bL3McJk6jfW+rtylNpumlEYOnOXOvEESS5iVdT2H6 +yAa+Tkvv/vMx/sZ8cApBWNromUuWyXi8mHwCKe0JgOYKOoICKuLJL8hWGSbueBwj/feTZU7n85iY +r83d2Z5AiDEoOqsuC7CsDCT6eiaY8xJhEPRdF/d+4niXVOKM6Cm6jBAyvd0zaziGfjk9DgNyp115 +j0WKWa5bIW4xRtVZjc8VX90xJc/bYNaBRHIpAlf2ltTW/+op2znFuCyKGo3Oy+dCMYYFaA6eFN0A +kLppRQjbbpCBhqcqBT/mhDn4t/lXX0ykeVoQDF7Va/81XwVRHmyjdanPUIPTfPRm94KNPQx96N97 +qA4bLJyuQHCH2u2nFoJavjVsIE4iYdm8UXrNemHcSxH5/mc0zy4EZmFcV5cjjPOGG0jfKq+nwf/Y +jj4Du9gqsPoUJbJRa4ZDhS4HIxaAjUz7tGM7zMN07RujHv41D198HRaG9Q7DlfEvr10lO1Hm13ZB +ONFLAzkopR6RctR9q5czxNM+4Gm2KHmgCY0c0f9BckgG/Jou5yD5m6Leie2uPAmvylezkolwQOQv +T8Jwg0DXJCxr5wkf09XHwQj02w47HAcLQxGEIYbpgNR12KvxAmLBsX5VYc8T1yaw15zLKYs4SgsO +kI26oQ== +-----END CERTIFICATE----- + +COMODO RSA Certification Authority +================================== +-----BEGIN CERTIFICATE----- +MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCBhTELMAkGA1UE +BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG +A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwHhcNMTAwMTE5MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMC +R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE +ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR6FSS0gpWsawNJN3Fz0Rn +dJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8Xpz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZ +FGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+ +5eNu/Nio5JIk2kNrYrhV/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pG +x8cgoLEfZd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z+pUX +2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7wqP/0uK3pN/u6uPQL +OvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZahSL0896+1DSJMwBGB7FY79tOi4lu3 +sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVICu9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+C +GCe01a60y1Dma/RMhnEw6abfFobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5 +WdYgGq/yapiqcrxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E +FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w +DQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvlwFTPoCWOAvn9sKIN9SCYPBMt +rFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+ +nq6PK7o9mfjYcwlYRm6mnPTXJ9OV2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSg +tZx8jb8uk2IntznaFxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwW +sRqZCuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiKboHGhfKp +pC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmckejkk9u+UJueBPSZI9FoJA +zMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yLS0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHq +ZJx64SIDqZxubw5lT2yHh17zbqD5daWbQOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk52 +7RH89elWsn2/x20Kk4yl0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7I +LaZRfyHBNVOFBkpdn627G190 +-----END CERTIFICATE----- + +USERTrust RSA Certification Authority +===================================== +-----BEGIN CERTIFICATE----- +MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCBiDELMAkGA1UE +BhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQK +ExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UE +BhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQK +ExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCAEmUXNg7D2wiz +0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2j +Y0K2dvKpOyuR+OJv0OwWIJAJPuLodMkYtJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFn +RghRy4YUVD+8M/5+bJz/Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O ++T23LLb2VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT79uq +/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6c0Plfg6lZrEpfDKE +Y1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmTYo61Zs8liM2EuLE/pDkP2QKe6xJM +lXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97lc6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8 +yexDJtC/QV9AqURE9JnnV4eeUB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+ +eLf8ZxXhyVeEHg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd +BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF +MAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPFUp/L+M+ZBn8b2kMVn54CVVeW +FPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KOVWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ +7l8wXEskEVX/JJpuXior7gtNn3/3ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQ +Eg9zKC7F4iRO/Fjs8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM +8WcRiQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYzeSf7dNXGi +FSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZXHlKYC6SQK5MNyosycdi +yA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9c +J2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRBVXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGw +sAvgnEzDHNb842m1R0aBL6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gx +Q+6IHdfGjjxDah2nGN59PRbxYvnKkKj9 +-----END CERTIFICATE----- + +USERTrust ECC Certification Authority +===================================== +-----BEGIN CERTIFICATE----- +MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDELMAkGA1UEBhMC +VVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU +aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMC +VVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU +aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqfloI+d61SRvU8Za2EurxtW2 +0eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinngo4N+LZfQYcTxmdwlkWOrfzCjtHDix6Ez +nPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0GA1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNV +HQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBB +HU6+4WMBzzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbWRNZu +9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= +-----END CERTIFICATE----- + +GlobalSign ECC Root CA - R4 +=========================== +-----BEGIN CERTIFICATE----- +MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEkMCIGA1UECxMb +R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD +EwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoXDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMb +R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD +EwpHbG9iYWxTaWduMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprl +OQcJFspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAwDgYDVR0P +AQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61FuOJAf/sKbvu+M8k8o4TV +MAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGXkPoUVy0D7O48027KqGx2vKLeuwIgJ6iF +JzWbVsaj8kfSt24bAgAXqmemFZHe+pTsewv4n4Q= +-----END CERTIFICATE----- + +GlobalSign ECC Root CA - R5 +=========================== +-----BEGIN CERTIFICATE----- +MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEkMCIGA1UECxMb +R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD +EwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoXDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMb +R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD +EwpHbG9iYWxTaWduMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6 +SFkc8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8kehOvRnkmS +h5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd +BgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYIKoZIzj0EAwMDaAAwZQIxAOVpEslu28Yx +uglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7 +yFz9SO8NdCKoCOJuxUnOxwy8p2Fp8fc74SrL+SvzZpA3 +-----END CERTIFICATE----- + +Staat der Nederlanden Root CA - G3 +================================== +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJOTDEeMBwGA1UE +CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFhdCBkZXIgTmVkZXJsYW5kZW4g +Um9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloXDTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMC +TkwxHjAcBgNVBAoMFVN0YWF0IGRlciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5l +ZGVybGFuZGVuIFJvb3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4y +olQPcPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WWIkYFsO2t +x1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqXxz8ecAgwoNzFs21v0IJy +EavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFyKJLZWyNtZrVtB0LrpjPOktvA9mxjeM3K +Tj215VKb8b475lRgsGYeCasH/lSJEULR9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUur +mkVLoR9BvUhTFXFkC4az5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU5 +1nus6+N86U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7Ngzp +07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHPbMk7ccHViLVlvMDo +FxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXtBznaqB16nzaeErAMZRKQFWDZJkBE +41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTtXUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMB +AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleu +yjWcLhL75LpdINyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD +U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwpLiniyMMB8jPq +KqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8Ipf3YF3qKS9Ysr1YvY2WTxB1 +v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixpgZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA +8KCWAg8zxXHzniN9lLf9OtMJgwYh/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b +8KKaa8MFSu1BYBQw0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0r +mj1AfsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq4BZ+Extq +1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR1VmiiXTTn74eS9fGbbeI +JG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/QFH1T/U67cjF68IeHRaVesd+QnGTbksV +tzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM94B7IWcnMFk= +-----END CERTIFICATE----- + +Staat der Nederlanden EV Root CA +================================ +-----BEGIN CERTIFICATE----- +MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJOTDEeMBwGA1UE +CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFhdCBkZXIgTmVkZXJsYW5kZW4g +RVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0yMjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5M +MR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRl +cmxhbmRlbiBFViBSb290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkk +SzrSM4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nCUiY4iKTW +O0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3dZ//BYY1jTw+bbRcwJu+r +0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46prfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8 +Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13lpJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gV +XJrm0w912fxBmJc+qiXbj5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr +08C+eKxCKFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS/ZbV +0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0XcgOPvZuM5l5Tnrmd +74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH1vI4gnPah1vlPNOePqc7nvQDs/nx +fRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrPpx9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwa +ivsnuL8wbqg7MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI +eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u2dfOWBfoqSmu +c0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHSv4ilf0X8rLiltTMMgsT7B/Zq +5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTCwPTxGfARKbalGAKb12NMcIxHowNDXLldRqAN +b/9Zjr7dn3LDWyvfjFvO5QxGbJKyCqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tN +f1zuacpzEPuKqf2evTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi +5Dp6Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIaGl6I6lD4 +WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeLeG9QgkRQP2YGiqtDhFZK +DyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGy +eUN51q1veieQA6TqJIc/2b3Z6fJfUEkc7uzXLg== +-----END CERTIFICATE----- + +IdenTrust Commercial Root CA 1 +============================== +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBKMQswCQYDVQQG +EwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBS +b290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQwMTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzES +MBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENB +IDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ld +hNlT3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU+ehcCuz/ +mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gpS0l4PJNgiCL8mdo2yMKi +1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1bVoE/c40yiTcdCMbXTMTEl3EASX2MN0C +XZ/g1Ue9tOsbobtJSdifWwLziuQkkORiT0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl +3ZBWzvurpWCdxJ35UrCLvYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzy +NeVJSQjKVsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZKdHzV +WYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHTc+XvvqDtMwt0viAg +xGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hvl7yTmvmcEpB4eoCHFddydJxVdHix +uuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5NiGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMC +AQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZI +hvcNAQELBQADggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH +6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwtLRvM7Kqas6pg +ghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93nAbowacYXVKV7cndJZ5t+qnt +ozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3+wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmV +YjzlVYA211QC//G5Xc7UI2/YRYRKW2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUX +feu+h1sXIFRRk0pTAwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/ro +kTLql1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG4iZZRHUe +2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZmUlO+KWA2yUPHGNiiskz +Z2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7R +cGzM7vRX+Bi6hG6H +-----END CERTIFICATE----- + +IdenTrust Public Sector Root CA 1 +================================= +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBNMQswCQYDVQQG +EwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3Rv +ciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcNMzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJV +UzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBS +b290IENBIDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTy +P4o7ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGyRBb06tD6 +Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlSbdsHyo+1W/CD80/HLaXI +rcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF/YTLNiCBWS2ab21ISGHKTN9T0a9SvESf +qy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoS +mJxZZoY+rfGwyj4GD3vwEUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFn +ol57plzy9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9VGxyh +LrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ2fjXctscvG29ZV/v +iDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsVWaFHVCkugyhfHMKiq3IXAAaOReyL +4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gDW/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8B +Af8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMw +DQYJKoZIhvcNAQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj +t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHVDRDtfULAj+7A +mgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9TaDKQGXSc3z1i9kKlT/YPyNt +GtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8GlwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFt +m6/n6J91eEyrRjuazr8FGF1NFTwWmhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMx +NRF4eKLg6TCMf4DfWN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4 +Mhn5+bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJtshquDDI +ajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhAGaQdp/lLQzfcaFpPz+vC +ZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ +3Wl9af0AVqW3rLatt8o+Ae+c +-----END CERTIFICATE----- + +Entrust Root Certification Authority - G2 +========================================= +-----BEGIN CERTIFICATE----- +MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMCVVMxFjAUBgNV +BAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVy +bXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ug +b25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIw +HhcNMDkwNzA3MTcyNTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoT +DUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMx +OTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25s +eTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP +/vaCeb9zYQYKpSfYs1/TRU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXz +HHfV1IWNcCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hWwcKU +s/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1U1+cPvQXLOZprE4y +TGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0jaWvYkxN4FisZDQSA/i2jZRjJKRx +AgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ6 +0B7vfec7aVHUbI2fkBJmqzANBgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5Z +iXMRrEPR9RP/jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ +Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v1fN2D807iDgi +nWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4RnAuknZoh8/CbCzB428Hch0P+ +vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmHVHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xO +e4pIb4tF9g== +-----END CERTIFICATE----- + +Entrust Root Certification Authority - EC1 +========================================== +-----BEGIN CERTIFICATE----- +MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkGA1UEBhMCVVMx +FjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVn +YWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXpl +ZCB1c2Ugb25seTEzMDEGA1UEAxMqRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +IC0gRUMxMB4XDTEyMTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYw +FAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2Fs +LXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQg +dXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAt +IEVDMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHy +AsWfoPZb1YsGGYZPUxBtByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef +9eNi1KlHBz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE +FLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVCR98crlOZF7ZvHH3h +vxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nXhTcGtXsI/esni0qU+eH6p44mCOh8 +kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G +-----END CERTIFICATE----- + +CFCA EV ROOT +============ +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJDTjEwMC4GA1UE +CgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNB +IEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkxMjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEw +MC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQD +DAxDRkNBIEVWIFJPT1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnV +BU03sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpLTIpTUnrD +7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5/ZOkVIBMUtRSqy5J35DN +uF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp7hZZLDRJGqgG16iI0gNyejLi6mhNbiyW +ZXvKWfry4t3uMCz7zEasxGPrb382KzRzEpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7 +xzbh72fROdOXW3NiGUgthxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9f +py25IGvPa931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqotaK8K +gWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNgTnYGmE69g60dWIol +hdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfVPKPtl8MeNPo4+QgO48BdK4PRVmrJ +tqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hvcWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAf +BgNVHSMEGDAWgBTj/i39KNALtbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB +/wQEAwIBBjAdBgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB +ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObTej/tUxPQ4i9q +ecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdLjOztUmCypAbqTuv0axn96/Ua +4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBSESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sG +E5uPhnEFtC+NiWYzKXZUmhH4J/qyP5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfX +BDrDMlI1Dlb4pd19xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjn +aH9dCi77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN5mydLIhy +PDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe/v5WOaHIz16eGWRGENoX +kbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+ZAAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3C +ekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su +-----END CERTIFICATE----- + +TรœRKTRUST Elektronik Sertifika Hizmet SaฤŸlayฤฑcฤฑsฤฑ H5 +========================================================= +-----BEGIN CERTIFICATE----- +MIIEJzCCAw+gAwIBAgIHAI4X/iQggTANBgkqhkiG9w0BAQsFADCBsTELMAkGA1UEBhMCVFIxDzAN +BgNVBAcMBkFua2FyYTFNMEsGA1UECgxEVMOcUktUUlVTVCBCaWxnaSDEsGxldGnFn2ltIHZlIEJp +bGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkgQS7Fni4xQjBABgNVBAMMOVTDnFJLVFJVU1Qg +RWxla3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSBINTAeFw0xMzA0MzAw +ODA3MDFaFw0yMzA0MjgwODA3MDFaMIGxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMU0w +SwYDVQQKDERUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnE +n2kgSGl6bWV0bGVyaSBBLsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBFbGVrdHJvbmlrIFNlcnRp +ZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIEg1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEApCUZ4WWe60ghUEoI5RHwWrom/4NZzkQqL/7hzmAD/I0Dpe3/a6i6zDQGn1k19uwsu537 +jVJp45wnEFPzpALFp/kRGml1bsMdi9GYjZOHp3GXDSHHmflS0yxjXVW86B8BSLlg/kJK9siArs1m +ep5Fimh34khon6La8eHBEJ/rPCmBp+EyCNSgBbGM+42WAA4+Jd9ThiI7/PS98wl+d+yG6w8z5UNP +9FR1bSmZLmZaQ9/LXMrI5Tjxfjs1nQ/0xVqhzPMggCTTV+wVunUlm+hkS7M0hO8EuPbJbKoCPrZV +4jI3X/xml1/N1p7HIL9Nxqw/dV8c7TKcfGkAaZHjIxhT6QIDAQABo0IwQDAdBgNVHQ4EFgQUVpkH +HtOsDGlktAxQR95DLL4gwPswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI +hvcNAQELBQADggEBAJ5FdnsXSDLyOIspve6WSk6BGLFRRyDN0GSxDsnZAdkJzsiZ3GglE9Rc8qPo +BP5yCccLqh0lVX6Wmle3usURehnmp349hQ71+S4pL+f5bFgWV1Al9j4uPqrtd3GqqpmWRgqujuwq +URawXs3qZwQcWDD1YIq9pr1N5Za0/EKJAWv2cMhQOQwt1WbZyNKzMrcbGW3LM/nfpeYVhDfwwvJl +lpKQd/Ct9JDpEXjXk4nAPQu6KfTomZ1yju2dL+6SfaHx/126M2CFYv4HAqGEVka+lgqaE9chTLd8 +B59OTj+RdPsnnRHM3eaxynFNExc5JsUpISuTKWqW+qtB4Uu2NQvAmxU= +-----END CERTIFICATE----- + +TรœRKTRUST Elektronik Sertifika Hizmet SaฤŸlayฤฑcฤฑsฤฑ H6 +========================================================= +-----BEGIN CERTIFICATE----- +MIIEJjCCAw6gAwIBAgIGfaHyZeyKMA0GCSqGSIb3DQEBCwUAMIGxMQswCQYDVQQGEwJUUjEPMA0G +A1UEBwwGQW5rYXJhMU0wSwYDVQQKDERUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmls +acWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBF +bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIEg2MB4XDTEzMTIxODA5 +MDQxMFoXDTIzMTIxNjA5MDQxMFowgbExCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExTTBL +BgNVBAoMRFTDnFJLVFJVU1QgQmlsZ2kgxLBsZXRpxZ9pbSB2ZSBCaWxpxZ9pbSBHw7x2ZW5sacSf +aSBIaXptZXRsZXJpIEEuxZ4uMUIwQAYDVQQDDDlUw5xSS1RSVVNUIEVsZWt0cm9uaWsgU2VydGlm +aWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLEgSDYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQCdsGjW6L0UlqMACprx9MfMkU1xeHe59yEmFXNRFpQJRwXiM/VomjX/3EsvMsew7eKC5W/a +2uqsxgbPJQ1BgfbBOCK9+bGlprMBvD9QFyv26WZV1DOzXPhDIHiTVRZwGTLmiddk671IUP320EED +wnS3/faAz1vFq6TWlRKb55cTMgPp1KtDWxbtMyJkKbbSk60vbNg9tvYdDjTu0n2pVQ8g9P0pu5Fb +HH3GQjhtQiht1AH7zYiXSX6484P4tZgvsycLSF5W506jM7NE1qXyGJTtHB6plVxiSvgNZ1GpryHV ++DKdeboaX+UEVU0TRv/yz3THGmNtwx8XEsMeED5gCLMxAgMBAAGjQjBAMB0GA1UdDgQWBBTdVRcT +9qzoSCHK77Wv0QAy7Z6MtTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG +9w0BAQsFAAOCAQEAb1gNl0OqFlQ+v6nfkkU/hQu7VtMMUszIv3ZnXuaqs6fvuay0EBQNdH49ba3R +fdCaqaXKGDsCQC4qnFAUi/5XfldcEQlLNkVS9z2sFP1E34uXI9TDwe7UU5X+LEr+DXCqu4svLcsy +o4LyVN/Y8t3XSHLuSqMplsNEzm61kod2pLv0kmzOLBQJZo6NrRa1xxsJYTvjIKIDgI6tflEATseW +hvtDmHd9KMeP2Cpu54Rvl0EpABZeTeIT6lnAY2c6RPuY/ATTMHKm9ocJV612ph1jmv3XZch4gyt1 +O6VbuA1df74jrlZVlFjvH4GMKrLN5ptjnhi85WsGtAuYSyher4hYyw== +-----END CERTIFICATE----- + +Certinomis - Root CA +==================== +-----BEGIN CERTIFICATE----- +MIIFkjCCA3qgAwIBAgIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJGUjETMBEGA1UEChMK +Q2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxHTAbBgNVBAMTFENlcnRpbm9taXMg +LSBSb290IENBMB4XDTEzMTAyMTA5MTcxOFoXDTMzMTAyMTA5MTcxOFowWjELMAkGA1UEBhMCRlIx +EzARBgNVBAoTCkNlcnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMR0wGwYDVQQDExRD +ZXJ0aW5vbWlzIC0gUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANTMCQos +P5L2fxSeC5yaah1AMGT9qt8OHgZbn1CF6s2Nq0Nn3rD6foCWnoR4kkjW4znuzuRZWJflLieY6pOo +d5tK8O90gC3rMB+12ceAnGInkYjwSond3IjmFPnVAy//ldu9n+ws+hQVWZUKxkd8aRi5pwP5ynap +z8dvtF4F/u7BUrJ1Mofs7SlmO/NKFoL21prbcpjp3vDFTKWrteoB4owuZH9kb/2jJZOLyKIOSY00 +8B/sWEUuNKqEUL3nskoTuLAPrjhdsKkb5nPJWqHZZkCqqU2mNAKthH6yI8H7KsZn9DS2sJVqM09x +RLWtwHkziOC/7aOgFLScCbAK42C++PhmiM1b8XcF4LVzbsF9Ri6OSyemzTUK/eVNfaoqoynHWmgE +6OXWk6RiwsXm9E/G+Z8ajYJJGYrKWUM66A0ywfRMEwNvbqY/kXPLynNvEiCL7sCCeN5LLsJJwx3t +FvYk9CcbXFcx3FXuqB5vbKziRcxXV4p1VxngtViZSTYxPDMBbRZKzbgqg4SGm/lg0h9tkQPTYKbV +PZrdd5A9NaSfD171UkRpucC63M9933zZxKyGIjK8e2uR73r4F2iw4lNVYC2vPsKD2NkJK/DAZNuH +i5HMkesE/Xa0lZrmFAYb1TQdvtj/dBxThZngWVJKYe2InmtJiUZ+IFrZ50rlau7SZRFDAgMBAAGj +YzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTvkUz1pcMw6C8I +6tNxIqSSaHh02TAfBgNVHSMEGDAWgBTvkUz1pcMw6C8I6tNxIqSSaHh02TANBgkqhkiG9w0BAQsF +AAOCAgEAfj1U2iJdGlg+O1QnurrMyOMaauo++RLrVl89UM7g6kgmJs95Vn6RHJk/0KGRHCwPT5iV +WVO90CLYiF2cN/z7ZMF4jIuaYAnq1fohX9B0ZedQxb8uuQsLrbWwF6YSjNRieOpWauwK0kDDPAUw +Pk2Ut59KA9N9J0u2/kTO+hkzGm2kQtHdzMjI1xZSg081lLMSVX3l4kLr5JyTCcBMWwerx20RoFAX +lCOotQqSD7J6wWAsOMwaplv/8gzjqh8c3LigkyfeY+N/IZ865Z764BNqdeuWXGKRlI5nU7aJ+BIJ +y29SWwNyhlCVCNSNh4YVH5Uk2KRvms6knZtt0rJ2BobGVgjF6wnaNsIbW0G+YSrjcOa4pvi2WsS9 +Iff/ql+hbHY5ZtbqTFXhADObE5hjyW/QASAJN1LnDE8+zbz1X5YnpyACleAu6AdBBR8Vbtaw5Bng +DwKTACdyxYvRVB9dSsNAl35VpnzBMwQUAR1JIGkLGZOdblgi90AMRgwjY/M50n92Uaf0yKHxDHYi +I0ZSKS3io0EHVmmY0gUJvGnHWmHNj4FgFU2A3ZDifcRQ8ow7bkrHxuaAKzyBvBGAFhAn1/DNP3nM +cyrDflOR1m749fPH0FFNjkulW+YZFzvWgQncItzujrnEj1PhZ7szuIgVRs/taTX/dQ1G885x4cVr +hkIGuUE= +-----END CERTIFICATE----- + +OISTE WISeKey Global Root GB CA +=============================== +-----BEGIN CERTIFICATE----- +MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBtMQswCQYDVQQG +EwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl +ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAw +MzJaFw0zOTEyMDExNTEwMzFaMG0xCzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYD +VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEds +b2JhbCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3HEokKtaX +scriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGxWuR51jIjK+FTzJlFXHtP +rby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk +9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNku7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4o +Qnc/nSMbsrY9gBQHTC5P99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvg +GUpuuy9rM2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZI +hvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrghcViXfa43FK8+5/ea4n32cZiZBKpD +dHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0 +VQreUGdNZtGn//3ZwLWoo4rOZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEui +HZeeevJuQHHfaPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic +Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= +-----END CERTIFICATE----- + +Certification Authority of WoSign G2 +==================================== +-----BEGIN CERTIFICATE----- +MIIDfDCCAmSgAwIBAgIQayXaioidfLwPBbOxemFFRDANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQG +EwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxLTArBgNVBAMTJENlcnRpZmljYXRpb24g +QXV0aG9yaXR5IG9mIFdvU2lnbiBHMjAeFw0xNDExMDgwMDU4NThaFw00NDExMDgwMDU4NThaMFgx +CzAJBgNVBAYTAkNOMRowGAYDVQQKExFXb1NpZ24gQ0EgTGltaXRlZDEtMCsGA1UEAxMkQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkgb2YgV29TaWduIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAvsXEoCKASU+/2YcRxlPhuw+9YH+v9oIOH9ywjj2X4FA8jzrvZjtFB5sg+OPXJYY1kBai +XW8wGQiHC38Gsp1ij96vkqVg1CuAmlI/9ZqD6TRay9nVYlzmDuDfBpgOgHzKtB0TiGsOqCR3A9Du +W/PKaZE1OVbFbeP3PU9ekzgkyhjpJMuSA93MHD0JcOQg5PGurLtzaaNjOg9FD6FKmsLRY6zLEPg9 +5k4ot+vElbGs/V6r+kHLXZ1L3PR8du9nfwB6jdKgGlxNIuG12t12s9R23164i5jIFFTMaxeSt+BK +v0mUYQs4kI9dJGwlezt52eJ+na2fmKEG/HgUYFf47oB3sQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMC +AQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU+mCp62XF3RYUCE4MD42b4Pdkr2cwDQYJKoZI +hvcNAQELBQADggEBAFfDejaCnI2Y4qtAqkePx6db7XznPWZaOzG73/MWM5H8fHulwqZm46qwtyeY +P0nXYGdnPzZPSsvxFPpahygc7Y9BMsaV+X3avXtbwrAh449G3CE4Q3RM+zD4F3LBMvzIkRfEzFg3 +TgvMWvchNSiDbGAtROtSjFA9tWwS1/oJu2yySrHFieT801LYYRf+epSEj3m2M1m6D8QL4nCgS3gu ++sif/a+RZQp4OBXllxcU3fngLDT4ONCEIgDAFFEYKwLcMFrw6AF8NTojrwjkr6qOKEJJLvD1mTS+ +7Q9LGOHSJDy7XUe3IfKN0QqZjuNuPq1w4I+5ysxugTH2e5x6eeRncRg= +-----END CERTIFICATE----- + +CA WoSign ECC Root +================== +-----BEGIN CERTIFICATE----- +MIICCTCCAY+gAwIBAgIQaEpYcIBr8I8C+vbe6LCQkDAKBggqhkjOPQQDAzBGMQswCQYDVQQGEwJD +TjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxGzAZBgNVBAMTEkNBIFdvU2lnbiBFQ0MgUm9v +dDAeFw0xNDExMDgwMDU4NThaFw00NDExMDgwMDU4NThaMEYxCzAJBgNVBAYTAkNOMRowGAYDVQQK +ExFXb1NpZ24gQ0EgTGltaXRlZDEbMBkGA1UEAxMSQ0EgV29TaWduIEVDQyBSb290MHYwEAYHKoZI +zj0CAQYFK4EEACIDYgAE4f2OuEMkq5Z7hcK6C62N4DrjJLnSsb6IOsq/Srj57ywvr1FQPEd1bPiU +t5v8KB7FVMxjnRZLU8HnIKvNrCXSf4/CwVqCXjCLelTOA7WRf6qU0NGKSMyCBSah1VES1ns2o0Iw +QDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUqv3VWqP2h4syhf3R +MluARZPzA7gwCgYIKoZIzj0EAwMDaAAwZQIxAOSkhLCB1T2wdKyUpOgOPQB0TKGXa/kNUTyh2Tv0 +Daupn75OcsqF1NnstTJFGG+rrQIwfcf3aWMvoeGY7xMQ0Xk/0f7qO3/eVvSQsRUR2LIiFdAvwyYu +a/GRspBl9JrmkO5K +-----END CERTIFICATE----- diff --git a/lib/Cake/Config/config.php b/lib/Cake/Config/config.php index f8528e8..cd3a398 100644 --- a/lib/Cake/Config/config.php +++ b/lib/Cake/Config/config.php @@ -2,20 +2,20 @@ /** * Core Configurations. * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package Cake.Config * @since CakePHP(tm) v 1.1.11.4062 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ + $versionFile = file(CAKE . 'VERSION.txt'); $config['Cake.version'] = trim(array_pop($versionFile)); return $config; diff --git a/lib/Cake/Config/routes.php b/lib/Cake/Config/routes.php index 4667c42..7bcc0c0 100644 --- a/lib/Cake/Config/routes.php +++ b/lib/Cake/Config/routes.php @@ -1,20 +1,17 @@ $pluginPattern); - $shortParams = array('routeClass' => 'PluginShortRoute', 'plugin' => $pluginPattern); + $match = array('plugin' => $pluginPattern, 'defaultRoute' => true); + $shortParams = array('routeClass' => 'PluginShortRoute', 'plugin' => $pluginPattern, 'defaultRoute' => true); foreach ($prefixes as $prefix) { $params = array('prefix' => $prefix, $prefix => true); @@ -71,11 +66,11 @@ if ($plugins = CakePlugin::loaded()) { foreach ($prefixes as $prefix) { $params = array('prefix' => $prefix, $prefix => true); $indexParams = $params + array('action' => 'index'); - Router::connect("/{$prefix}/:controller", $indexParams); - Router::connect("/{$prefix}/:controller/:action/*", $params); + Router::connect("/{$prefix}/:controller", $indexParams, array('defaultRoute' => true)); + Router::connect("/{$prefix}/:controller/:action/*", $params, array('defaultRoute' => true)); } -Router::connect('/:controller', array('action' => 'index')); -Router::connect('/:controller/:action/*'); +Router::connect('/:controller', array('action' => 'index'), array('defaultRoute' => true)); +Router::connect('/:controller/:action/*', array(), array('defaultRoute' => true)); $namedConfig = Router::namedConfig(); if ($namedConfig['rules'] === false) { @@ -84,3 +79,4 @@ if ($namedConfig['rules'] === false) { unset($namedConfig, $params, $indexParams, $prefix, $prefixes, $shortParams, $match, $pluginPattern, $plugins, $key, $value); + diff --git a/lib/Cake/Config/unicode/casefolding/0080_00ff.php b/lib/Cake/Config/unicode/casefolding/0080_00ff.php index 542f47d..76a8654 100644 --- a/lib/Cake/Config/unicode/casefolding/0080_00ff.php +++ b/lib/Cake/Config/unicode/casefolding/0080_00ff.php @@ -8,19 +8,18 @@ * @see http://www.unicode.org/Public/UNIDATA/CaseFolding.txt * @see http://www.unicode.org/reports/tr21/tr21-5.html * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package Cake.Config.unicode.casefolding * @since CakePHP(tm) v 1.2.0.5691 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ /** diff --git a/lib/Cake/Config/unicode/casefolding/0100_017f.php b/lib/Cake/Config/unicode/casefolding/0100_017f.php index e8c3ff6..80129e7 100644 --- a/lib/Cake/Config/unicode/casefolding/0100_017f.php +++ b/lib/Cake/Config/unicode/casefolding/0100_017f.php @@ -8,19 +8,18 @@ * @see http://www.unicode.org/Public/UNIDATA/CaseFolding.txt * @see http://www.unicode.org/reports/tr21/tr21-5.html * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package Cake.Config.unicode.casefolding * @since CakePHP(tm) v 1.2.0.5691 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ /** diff --git a/lib/Cake/Config/unicode/casefolding/0180_024F.php b/lib/Cake/Config/unicode/casefolding/0180_024F.php index e8baaa3..763ba39 100644 --- a/lib/Cake/Config/unicode/casefolding/0180_024F.php +++ b/lib/Cake/Config/unicode/casefolding/0180_024F.php @@ -8,19 +8,18 @@ * @see http://www.unicode.org/Public/UNIDATA/CaseFolding.txt * @see http://www.unicode.org/reports/tr21/tr21-5.html * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package Cake.Config.unicode.casefolding * @since CakePHP(tm) v 1.2.0.5691 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ /** diff --git a/lib/Cake/Config/unicode/casefolding/0250_02af.php b/lib/Cake/Config/unicode/casefolding/0250_02af.php index 6ffa59d..c85b28e 100644 --- a/lib/Cake/Config/unicode/casefolding/0250_02af.php +++ b/lib/Cake/Config/unicode/casefolding/0250_02af.php @@ -8,19 +8,18 @@ * @see http://www.unicode.org/Public/UNIDATA/CaseFolding.txt * @see http://www.unicode.org/reports/tr21/tr21-5.html * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package Cake.Config.unicode.casefolding * @since CakePHP(tm) v 1.2.0.6833 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ /** diff --git a/lib/Cake/Config/unicode/casefolding/0370_03ff.php b/lib/Cake/Config/unicode/casefolding/0370_03ff.php index bb7ecde..345b0f9 100644 --- a/lib/Cake/Config/unicode/casefolding/0370_03ff.php +++ b/lib/Cake/Config/unicode/casefolding/0370_03ff.php @@ -8,19 +8,18 @@ * @see http://www.unicode.org/Public/UNIDATA/CaseFolding.txt * @see http://www.unicode.org/reports/tr21/tr21-5.html * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package Cake.Config.unicode.casefolding * @since CakePHP(tm) v 1.2.0.5691 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ /** diff --git a/lib/Cake/Config/unicode/casefolding/0400_04ff.php b/lib/Cake/Config/unicode/casefolding/0400_04ff.php index 7a3f93a..126fc2a 100644 --- a/lib/Cake/Config/unicode/casefolding/0400_04ff.php +++ b/lib/Cake/Config/unicode/casefolding/0400_04ff.php @@ -8,19 +8,18 @@ * @see http://www.unicode.org/Public/UNIDATA/CaseFolding.txt * @see http://www.unicode.org/reports/tr21/tr21-5.html * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package Cake.Config.unicode.casefolding * @since CakePHP(tm) v 1.2.0.5691 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ /** diff --git a/lib/Cake/Config/unicode/casefolding/0500_052f.php b/lib/Cake/Config/unicode/casefolding/0500_052f.php index 73b81fa..cbc15ef 100644 --- a/lib/Cake/Config/unicode/casefolding/0500_052f.php +++ b/lib/Cake/Config/unicode/casefolding/0500_052f.php @@ -8,19 +8,18 @@ * @see http://www.unicode.org/Public/UNIDATA/CaseFolding.txt * @see http://www.unicode.org/reports/tr21/tr21-5.html * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package Cake.Config.unicode.casefolding * @since CakePHP(tm) v 1.2.0.5691 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ /** diff --git a/lib/Cake/Config/unicode/casefolding/0530_058f.php b/lib/Cake/Config/unicode/casefolding/0530_058f.php index 4ffb553..a139a67 100644 --- a/lib/Cake/Config/unicode/casefolding/0530_058f.php +++ b/lib/Cake/Config/unicode/casefolding/0530_058f.php @@ -8,19 +8,18 @@ * @see http://www.unicode.org/Public/UNIDATA/CaseFolding.txt * @see http://www.unicode.org/reports/tr21/tr21-5.html * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package Cake.Config.unicode.casefolding * @since CakePHP(tm) v 1.2.0.5691 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ /** diff --git a/lib/Cake/Config/unicode/casefolding/1e00_1eff.php b/lib/Cake/Config/unicode/casefolding/1e00_1eff.php index 5b534a3..a8f75e0 100644 --- a/lib/Cake/Config/unicode/casefolding/1e00_1eff.php +++ b/lib/Cake/Config/unicode/casefolding/1e00_1eff.php @@ -8,19 +8,18 @@ * @see http://www.unicode.org/Public/UNIDATA/CaseFolding.txt * @see http://www.unicode.org/reports/tr21/tr21-5.html * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package Cake.Config.unicode.casefolding * @since CakePHP(tm) v 1.2.0.5691 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ /** diff --git a/lib/Cake/Config/unicode/casefolding/1f00_1fff.php b/lib/Cake/Config/unicode/casefolding/1f00_1fff.php index be09aa5..c2fc430 100644 --- a/lib/Cake/Config/unicode/casefolding/1f00_1fff.php +++ b/lib/Cake/Config/unicode/casefolding/1f00_1fff.php @@ -8,19 +8,18 @@ * @see http://www.unicode.org/Public/UNIDATA/CaseFolding.txt * @see http://www.unicode.org/reports/tr21/tr21-5.html * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package Cake.Config.unicode.casefolding * @since CakePHP(tm) v 1.2.0.5691 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ /** diff --git a/lib/Cake/Config/unicode/casefolding/2100_214f.php b/lib/Cake/Config/unicode/casefolding/2100_214f.php index 77705ed..fbc9b84 100644 --- a/lib/Cake/Config/unicode/casefolding/2100_214f.php +++ b/lib/Cake/Config/unicode/casefolding/2100_214f.php @@ -8,19 +8,18 @@ * @see http://www.unicode.org/Public/UNIDATA/CaseFolding.txt * @see http://www.unicode.org/reports/tr21/tr21-5.html * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package Cake.Config.unicode.casefolding * @since CakePHP(tm) v 1.2.0.5691 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ /** diff --git a/lib/Cake/Config/unicode/casefolding/2150_218f.php b/lib/Cake/Config/unicode/casefolding/2150_218f.php index 8821fbd..1828122 100644 --- a/lib/Cake/Config/unicode/casefolding/2150_218f.php +++ b/lib/Cake/Config/unicode/casefolding/2150_218f.php @@ -8,19 +8,18 @@ * @see http://www.unicode.org/Public/UNIDATA/CaseFolding.txt * @see http://www.unicode.org/reports/tr21/tr21-5.html * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package Cake.Config.unicode.casefolding * @since CakePHP(tm) v 1.2.0.5691 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ /** diff --git a/lib/Cake/Config/unicode/casefolding/2460_24ff.php b/lib/Cake/Config/unicode/casefolding/2460_24ff.php index 08b2615..23d2870 100644 --- a/lib/Cake/Config/unicode/casefolding/2460_24ff.php +++ b/lib/Cake/Config/unicode/casefolding/2460_24ff.php @@ -8,19 +8,18 @@ * @see http://www.unicode.org/Public/UNIDATA/CaseFolding.txt * @see http://www.unicode.org/reports/tr21/tr21-5.html * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package Cake.Config.unicode.casefolding * @since CakePHP(tm) v 1.2.0.5691 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ /** diff --git a/lib/Cake/Config/unicode/casefolding/2c00_2c5f.php b/lib/Cake/Config/unicode/casefolding/2c00_2c5f.php index 185f390..00f4584 100644 --- a/lib/Cake/Config/unicode/casefolding/2c00_2c5f.php +++ b/lib/Cake/Config/unicode/casefolding/2c00_2c5f.php @@ -8,19 +8,18 @@ * @see http://www.unicode.org/Public/UNIDATA/CaseFolding.txt * @see http://www.unicode.org/reports/tr21/tr21-5.html * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package Cake.Config.unicode.casefolding * @since CakePHP(tm) v 1.2.0.5691 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ /** diff --git a/lib/Cake/Config/unicode/casefolding/2c60_2c7f.php b/lib/Cake/Config/unicode/casefolding/2c60_2c7f.php index f0f1e90..5896b8d 100644 --- a/lib/Cake/Config/unicode/casefolding/2c60_2c7f.php +++ b/lib/Cake/Config/unicode/casefolding/2c60_2c7f.php @@ -8,19 +8,18 @@ * @see http://www.unicode.org/Public/UNIDATA/CaseFolding.txt * @see http://www.unicode.org/reports/tr21/tr21-5.html * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package Cake.Config.unicode.casefolding * @since CakePHP(tm) v 1.2.0.5691 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ /** diff --git a/lib/Cake/Config/unicode/casefolding/2c80_2cff.php b/lib/Cake/Config/unicode/casefolding/2c80_2cff.php index c073a53..afc89ba 100644 --- a/lib/Cake/Config/unicode/casefolding/2c80_2cff.php +++ b/lib/Cake/Config/unicode/casefolding/2c80_2cff.php @@ -8,19 +8,18 @@ * @see http://www.unicode.org/Public/UNIDATA/CaseFolding.txt * @see http://www.unicode.org/reports/tr21/tr21-5.html * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package Cake.Config.unicode.casefolding * @since CakePHP(tm) v 1.2.0.5691 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ /** diff --git a/lib/Cake/Config/unicode/casefolding/ff00_ffef.php b/lib/Cake/Config/unicode/casefolding/ff00_ffef.php index 22d7a2d..134d4ed 100644 --- a/lib/Cake/Config/unicode/casefolding/ff00_ffef.php +++ b/lib/Cake/Config/unicode/casefolding/ff00_ffef.php @@ -8,19 +8,18 @@ * @see http://www.unicode.org/Public/UNIDATA/CaseFolding.txt * @see http://www.unicode.org/reports/tr21/tr21-5.html * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package Cake.Config.unicode.casefolding * @since CakePHP(tm) v 1.2.0.5691 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ /** diff --git a/lib/Cake/Configure/ConfigReaderInterface.php b/lib/Cake/Configure/ConfigReaderInterface.php index f137355..ddea4e2 100644 --- a/lib/Cake/Configure/ConfigReaderInterface.php +++ b/lib/Cake/Configure/ConfigReaderInterface.php @@ -1,16 +1,17 @@ array('password' => 'secret'))` @@ -33,10 +34,10 @@ App::uses('Hash', 'Utility'); * You can nest properties as deeply as needed using `.`'s. In addition to using `.` you * can use standard ini section notation to create nested structures: * - * {{{ + * ``` * [section] * key = value - * }}} + * ``` * * Once loaded into Configure, the above would be accessed using: * @@ -94,30 +95,14 @@ class IniReader implements ConfigReaderInterface { * @return array Parsed configuration values. * @throws ConfigureException when files don't exist. * Or when files contain '..' as this could lead to abusive reads. - * @throws ConfigureException */ public function read($key) { if (strpos($key, '..') !== false) { throw new ConfigureException(__d('cake_dev', 'Cannot load configuration files with ../ in them.')); } - if (substr($key, -8) === '.ini.php') { - $key = substr($key, 0, -8); - list($plugin, $key) = pluginSplit($key); - $key .= '.ini.php'; - } else { - if (substr($key, -4) === '.ini') { - $key = substr($key, 0, -4); - } - list($plugin, $key) = pluginSplit($key); - $key .= '.ini'; - } - if ($plugin) { - $file = App::pluginPath($plugin) . 'Config' . DS . $key; - } else { - $file = $this->_path . $key; - } - if (!is_file($file)) { + $file = $this->_getFilePath($key); + if (!is_file(realpath($file))) { throw new ConfigureException(__d('cake_dev', 'Could not load configuration file: %s', $file)); } @@ -165,36 +150,39 @@ class IniReader implements ConfigReaderInterface { /** * Dumps the state of Configure data into an ini formatted string. * - * @param string $filename The filename on $this->_path to save into. - * Extension ".ini" will be automatically appended if not included in filename. + * @param string $key The identifier to write to. If the key has a . it will be treated + * as a plugin prefix. * @param array $data The data to convert to ini file. * @return int Bytes saved. */ - public function dump($filename, $data) { + public function dump($key, $data) { $result = array(); - foreach ($data as $key => $value) { - if ($key[0] != '[') { - $result[] = "[$key]"; + foreach ($data as $k => $value) { + $isSection = false; + if ($k[0] !== '[') { + $result[] = "[$k]"; + $isSection = true; } if (is_array($value)) { - $keyValues = Hash::flatten($value, '.'); - foreach ($keyValues as $k => $v) { - $result[] = "$k = " . $this->_value($v); + $kValues = Hash::flatten($value, '.'); + foreach ($kValues as $k2 => $v) { + $result[] = "$k2 = " . $this->_value($v); } } + if ($isSection) { + $result[] = ''; + } } - $contents = join("\n", $result); + $contents = trim(implode("\n", $result)); - if (substr($filename, -4) !== '.ini') { - $filename .= '.ini'; - } - return file_put_contents($this->_path . $filename, $contents); + $filename = $this->_getFilePath($key); + return file_put_contents($filename, $contents); } /** * Converts a value into the ini equivalent * - * @param mixed $value to export. + * @param mixed $val Value to export. * @return string String value for ini file. */ protected function _value($val) { @@ -210,4 +198,33 @@ class IniReader implements ConfigReaderInterface { return (string)$val; } +/** + * Get file path + * + * @param string $key The identifier to write to. If the key has a . it will be treated + * as a plugin prefix. + * @return string Full file path + */ + protected function _getFilePath($key) { + if (substr($key, -8) === '.ini.php') { + $key = substr($key, 0, -8); + list($plugin, $key) = pluginSplit($key); + $key .= '.ini.php'; + } else { + if (substr($key, -4) === '.ini') { + $key = substr($key, 0, -4); + } + list($plugin, $key) = pluginSplit($key); + $key .= '.ini'; + } + + if ($plugin) { + $file = CakePlugin::path($plugin) . 'Config' . DS . $key; + } else { + $file = $this->_path . $key; + } + + return $file; + } + } diff --git a/lib/Cake/Configure/PhpReader.php b/lib/Cake/Configure/PhpReader.php index 843313c..d15a41b 100644 --- a/lib/Cake/Configure/PhpReader.php +++ b/lib/Cake/Configure/PhpReader.php @@ -2,20 +2,21 @@ /** * PhpReader file * - * PHP 5 - * - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://book.cakephp.org/2.0/en/development/configuration.html#loading-configuration-files CakePHP(tm) Configuration * @package Cake.Configure * @since CakePHP(tm) v 2.0 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ +App::uses('CakePlugin', 'Core'); + /** * PHP Reader allows Configure to load configuration values from * files containing simple PHP arrays. @@ -37,7 +38,7 @@ class PhpReader implements ConfigReaderInterface { /** * Constructor for PHP Config file reading. * - * @param string $path The path to read config files from. Defaults to APP . 'Config' . DS + * @param string $path The path to read config files from. Defaults to APP . 'Config' . DS */ public function __construct($path = null) { if (!$path) { @@ -49,10 +50,10 @@ class PhpReader implements ConfigReaderInterface { /** * Read a config file and return its contents. * - * Files with `.` in the name will be treated as values in plugins. Instead of reading from - * the initialized path, plugin keys will be located using App::pluginPath(). + * Files with `.` in the name will be treated as values in plugins. Instead of reading from + * the initialized path, plugin keys will be located using CakePlugin::path(). * - * @param string $key The identifier to read from. If the key has a . it will be treated + * @param string $key The identifier to read from. If the key has a . it will be treated * as a plugin prefix. * @return array Parsed configuration values. * @throws ConfigureException when files don't exist or they don't contain `$config`. @@ -62,26 +63,15 @@ class PhpReader implements ConfigReaderInterface { if (strpos($key, '..') !== false) { throw new ConfigureException(__d('cake_dev', 'Cannot load configuration files with ../ in them.')); } - if (substr($key, -4) === '.php') { - $key = substr($key, 0, -4); - } - list($plugin, $key) = pluginSplit($key); - $key .= '.php'; - if ($plugin) { - $file = App::pluginPath($plugin) . 'Config' . DS . $key; - } else { - $file = $this->_path . $key; - } - if (!is_file($file)) { + $file = $this->_getFilePath($key); + if (!is_file(realpath($file))) { throw new ConfigureException(__d('cake_dev', 'Could not load configuration file: %s', $file)); } include $file; if (!isset($config)) { - throw new ConfigureException( - sprintf(__d('cake_dev', 'No variable $config found in %s'), $file) - ); + throw new ConfigureException(__d('cake_dev', 'No variable %s found in %s', '$config', $file)); } return $config; } @@ -90,18 +80,39 @@ class PhpReader implements ConfigReaderInterface { * Converts the provided $data into a string of PHP code that can * be used saved into a file and loaded later. * - * @param string $filename The filename to create on $this->_path. - * Extension ".php" will be automatically appended if not included in filename. + * @param string $key The identifier to write to. If the key has a . it will be treated + * as a plugin prefix. * @param array $data Data to dump. * @return int Bytes saved. */ - public function dump($filename, $data) { + public function dump($key, $data) { $contents = '_getFilePath($key); + return file_put_contents($filename, $contents); + } + +/** + * Get file path + * + * @param string $key The identifier to write to. If the key has a . it will be treated + * as a plugin prefix. + * @return string Full file path + */ + protected function _getFilePath($key) { + if (substr($key, -4) === '.php') { + $key = substr($key, 0, -4); } - return file_put_contents($this->_path . $filename, $contents); + list($plugin, $key) = pluginSplit($key); + $key .= '.php'; + + if ($plugin) { + $file = CakePlugin::path($plugin) . 'Config' . DS . $key; + } else { + $file = $this->_path . $key; + } + + return $file; } } diff --git a/lib/Cake/Console/Command/AclShell.php b/lib/Cake/Console/Command/AclShell.php index 4a93528..15536eb 100644 --- a/lib/Cake/Console/Command/AclShell.php +++ b/lib/Cake/Console/Command/AclShell.php @@ -2,18 +2,17 @@ /** * Acl Shell provides Acl access in the CLI environment * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @since CakePHP(tm) v 1.2.0.5012 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ App::uses('AppShell', 'Console/Command'); @@ -24,8 +23,8 @@ App::uses('DbAcl', 'Model'); App::uses('Hash', 'Utility'); /** - * Shell for ACL management. This console is known to have issues with zend.ze1_compatibility_mode - * being enabled. Be sure to turn it off when using this shell. + * Shell for ACL management. This console is known to have issues with zend.ze1_compatibility_mode + * being enabled. Be sure to turn it off when using this shell. * * @package Cake.Console.Command */ @@ -75,22 +74,22 @@ class AclShell extends AppShell { App::uses($class, $plugin . 'Controller/Component/Acl'); if (!in_array($class, array('DbAcl', 'DB_ACL')) && !is_subclass_of($class, 'DbAcl')) { $out = "--------------------------------------------------\n"; - $out .= __d('cake_console', 'Error: Your current Cake configuration is set to an ACL implementation other than DB.') . "\n"; + $out .= __d('cake_console', 'Error: Your current CakePHP configuration is set to an ACL implementation other than DB.') . "\n"; $out .= __d('cake_console', 'Please change your core config to reflect your decision to use DbAcl before attempting to use this script') . "\n"; $out .= "--------------------------------------------------\n"; $out .= __d('cake_console', 'Current ACL Classname: %s', $class) . "\n"; $out .= "--------------------------------------------------\n"; $this->err($out); - $this->_stop(); + return $this->_stop(); } if ($this->command) { if (!config('database')) { - $this->out(__d('cake_console', 'Your database configuration was not found. Take a moment to create one.'), true); + $this->out(__d('cake_console', 'Your database configuration was not found. Take a moment to create one.')); $this->args = null; return $this->DbConfig->execute(); } - require_once (APP . 'Config' . DS . 'database.php'); + require_once APP . 'Config' . DS . 'database.php'; if (!in_array($this->command, array('initdb'))) { $collection = new ComponentCollection(); @@ -121,14 +120,14 @@ class AclShell extends AppShell { $class = ucfirst($this->args[0]); $parent = $this->parseIdentifier($this->args[1]); - if (!empty($parent) && $parent != '/' && $parent != 'root') { + if (!empty($parent) && $parent !== '/' && $parent !== 'root') { $parent = $this->_getNodeId($class, $parent); } else { $parent = null; } $data = $this->parseIdentifier($this->args[2]); - if (is_string($data) && $data != '/') { + if (is_string($data) && $data !== '/') { $data = array('alias' => $data); } elseif (is_string($data)) { $this->error(__d('cake_console', '/ can not be used as an alias!') . __d('cake_console', " / is the root, please supply a sub alias")); @@ -144,7 +143,8 @@ class AclShell extends AppShell { } /** - * Delete an ARO/ACO node. + * Delete an ARO/ACO node. Note there may be (as a result of poor configuration) + * multiple records with the same logical identifier. All are deleted. * * @return void */ @@ -152,12 +152,18 @@ class AclShell extends AppShell { extract($this->_dataVars()); $identifier = $this->parseIdentifier($this->args[1]); - $nodeId = $this->_getNodeId($class, $identifier); - - if (!$this->Acl->{$class}->delete($nodeId)) { - $this->error(__d('cake_console', 'Node Not Deleted') . __d('cake_console', 'There was an error deleting the %s. Check that the node exists.', $class) . "\n"); + if (is_string($identifier)) { + $identifier = array('alias' => $identifier); + } + + if ($this->Acl->{$class}->find('all', array('conditions' => $identifier))) { + if (!$this->Acl->{$class}->deleteAll($identifier)) { + $this->error(__d('cake_console', 'Node Not Deleted. ') . __d('cake_console', 'There was an error deleting the %s.', $class) . "\n"); + } + $this->out(__d('cake_console', '%s deleted.', $class), 2); + } else { + $this->error(__d('cake_console', 'Node Not Deleted. ') . __d('cake_console', 'There was an error deleting the %s. Node does not exist.', $class) . "\n"); } - $this->out(__d('cake_console', '%s deleted.', $class), 2); } /** @@ -178,9 +184,9 @@ class AclShell extends AppShell { ); $this->Acl->{$class}->create(); if (!$this->Acl->{$class}->save($data)) { - $this->out(__d('cake_console', 'Error in setting new parent. Please make sure the parent node exists, and is not a descendant of the node specified.'), true); + $this->out(__d('cake_console', 'Error in setting new parent. Please make sure the parent node exists, and is not a descendant of the node specified.')); } else { - $this->out(__d('cake_console', 'Node parent set to %s', $this->args[2]) . "\n", true); + $this->out(__d('cake_console', 'Node parent set to %s', $this->args[2]) . "\n"); } } @@ -214,7 +220,7 @@ class AclShell extends AppShell { * * @param string $class Class name that is being used. * @param array $node Array of node information. - * @param integer $indent indent level. + * @param int $indent indent level. * @return void */ protected function _outputNode($class, $node, $indent) { @@ -236,9 +242,9 @@ class AclShell extends AppShell { extract($this->_getParams()); if ($this->Acl->check($aro, $aco, $action)) { - $this->out(__d('cake_console', '%s is allowed.', $aroName), true); + $this->out(__d('cake_console', '%s is allowed.', $aroName)); } else { - $this->out(__d('cake_console', '%s is not allowed.', $aroName), true); + $this->out(__d('cake_console', '%s is not allowed.', $aroName)); } } @@ -251,9 +257,9 @@ class AclShell extends AppShell { extract($this->_getParams()); if ($this->Acl->allow($aro, $aco, $action)) { - $this->out(__d('cake_console', 'Permission granted.'), true); + $this->out(__d('cake_console', 'Permission granted.')); } else { - $this->out(__d('cake_console', 'Permission was not granted.'), true); + $this->out(__d('cake_console', 'Permission was not granted.')); } } @@ -266,9 +272,9 @@ class AclShell extends AppShell { extract($this->_getParams()); if ($this->Acl->deny($aro, $aco, $action)) { - $this->out(__d('cake_console', 'Permission denied.'), true); + $this->out(__d('cake_console', 'Permission denied.')); } else { - $this->out(__d('cake_console', 'Permission was not denied.'), true); + $this->out(__d('cake_console', 'Permission was not denied.')); } } @@ -281,9 +287,9 @@ class AclShell extends AppShell { extract($this->_getParams()); if ($this->Acl->inherit($aro, $aco, $action)) { - $this->out(__d('cake_console', 'Permission inherited.'), true); + $this->out(__d('cake_console', 'Permission inherited.')); } else { - $this->out(__d('cake_console', 'Permission was not inherited.'), true); + $this->out(__d('cake_console', 'Permission was not inherited.')); } } @@ -324,7 +330,7 @@ class AclShell extends AppShell { $this->hr(); $stack = array(); - $last = null; + $last = null; foreach ($nodes as $n) { $stack[] = $n; @@ -357,9 +363,9 @@ class AclShell extends AppShell { } /** - * Get the option parser. + * Gets the option parser instance and configures it. * - * @return void + * @return ConsoleOptionParser */ public function getOptionParser() { $parser = parent::getOptionParser(); @@ -372,148 +378,148 @@ class AclShell extends AppShell { $parser->description( __d('cake_console', 'A console tool for managing the DbAcl') - )->addSubcommand('create', array( - 'help' => __d('cake_console', 'Create a new ACL node'), - 'parser' => array( - 'description' => __d('cake_console', 'Creates a new ACL object under the parent'), - 'arguments' => array( - 'type' => $type, - 'parent' => array( - 'help' => __d('cake_console', 'The node selector for the parent.'), - 'required' => true - ), - 'alias' => array( - 'help' => __d('cake_console', 'The alias to use for the newly created node.'), - 'required' => true - ) - ) - ) - ))->addSubcommand('delete', array( - 'help' => __d('cake_console', 'Deletes the ACL object with the given reference'), - 'parser' => array( - 'description' => __d('cake_console', 'Delete an ACL node.'), - 'arguments' => array( - 'type' => $type, - 'node' => array( - 'help' => __d('cake_console', 'The node identifier to delete.'), - 'required' => true, - ) - ) - ) - ))->addSubcommand('setparent', array( - 'help' => __d('cake_console', 'Moves the ACL node under a new parent.'), - 'parser' => array( - 'description' => __d('cake_console', 'Moves the ACL object specified by beneath '), - 'arguments' => array( - 'type' => $type, - 'node' => array( - 'help' => __d('cake_console', 'The node to move'), - 'required' => true, - ), - 'parent' => array( - 'help' => __d('cake_console', 'The new parent for .'), - 'required' => true - ) - ) - ) - ))->addSubcommand('getpath', array( - 'help' => __d('cake_console', 'Print out the path to an ACL node.'), - 'parser' => array( - 'description' => array( - __d('cake_console', "Returns the path to the ACL object specified by ."), - __d('cake_console', "This command is useful in determining the inheritance of permissions for a certain object in the tree.") + )->addSubcommand('create', array( + 'help' => __d('cake_console', 'Create a new ACL node'), + 'parser' => array( + 'description' => __d('cake_console', 'Creates a new ACL object under the parent'), + 'epilog' => __d('cake_console', 'You can use `root` as the parent when creating nodes to create top level nodes.'), + 'arguments' => array( + 'type' => $type, + 'parent' => array( + 'help' => __d('cake_console', 'The node selector for the parent.'), + 'required' => true ), - 'arguments' => array( - 'type' => $type, - 'node' => array( - 'help' => __d('cake_console', 'The node to get the path of'), - 'required' => true, - ) + 'alias' => array( + 'help' => __d('cake_console', 'The alias to use for the newly created node.'), + 'required' => true ) ) - ))->addSubcommand('check', array( - 'help' => __d('cake_console', 'Check the permissions between an ACO and ARO.'), - 'parser' => array( - 'description' => array( - __d('cake_console', 'Use this command to check ACL permissions.') + ) + ))->addSubcommand('delete', array( + 'help' => __d('cake_console', 'Deletes the ACL object with the given reference'), + 'parser' => array( + 'description' => __d('cake_console', 'Delete an ACL node.'), + 'arguments' => array( + 'type' => $type, + 'node' => array( + 'help' => __d('cake_console', 'The node identifier to delete.'), + 'required' => true, + ) + ) + ) + ))->addSubcommand('setparent', array( + 'help' => __d('cake_console', 'Moves the ACL node under a new parent.'), + 'parser' => array( + 'description' => __d('cake_console', 'Moves the ACL object specified by beneath '), + 'arguments' => array( + 'type' => $type, + 'node' => array( + 'help' => __d('cake_console', 'The node to move'), + 'required' => true, ), - 'arguments' => array( - 'aro' => array('help' => __d('cake_console', 'ARO to check.'), 'required' => true), - 'aco' => array('help' => __d('cake_console', 'ACO to check.'), 'required' => true), - 'action' => array('help' => __d('cake_console', 'Action to check'), 'default' => 'all') + 'parent' => array( + 'help' => __d('cake_console', 'The new parent for .'), + 'required' => true ) ) - ))->addSubcommand('grant', array( - 'help' => __d('cake_console', 'Grant an ARO permissions to an ACO.'), - 'parser' => array( - 'description' => array( - __d('cake_console', 'Use this command to grant ACL permissions. Once executed, the ARO specified (and its children, if any) will have ALLOW access to the specified ACO action (and the ACO\'s children, if any).') - ), - 'arguments' => array( - 'aro' => array('help' => __d('cake_console', 'ARO to grant permission to.'), 'required' => true), - 'aco' => array('help' => __d('cake_console', 'ACO to grant access to.'), 'required' => true), - 'action' => array('help' => __d('cake_console', 'Action to grant'), 'default' => 'all') + ) + ))->addSubcommand('getpath', array( + 'help' => __d('cake_console', 'Print out the path to an ACL node.'), + 'parser' => array( + 'description' => array( + __d('cake_console', "Returns the path to the ACL object specified by ."), + __d('cake_console', "This command is useful in determining the inheritance of permissions for a certain object in the tree.") + ), + 'arguments' => array( + 'type' => $type, + 'node' => array( + 'help' => __d('cake_console', 'The node to get the path of'), + 'required' => true, ) ) - ))->addSubcommand('deny', array( - 'help' => __d('cake_console', 'Deny an ARO permissions to an ACO.'), - 'parser' => array( - 'description' => array( - __d('cake_console', 'Use this command to deny ACL permissions. Once executed, the ARO specified (and its children, if any) will have DENY access to the specified ACO action (and the ACO\'s children, if any).') - ), - 'arguments' => array( - 'aro' => array('help' => __d('cake_console', 'ARO to deny.'), 'required' => true), - 'aco' => array('help' => __d('cake_console', 'ACO to deny.'), 'required' => true), - 'action' => array('help' => __d('cake_console', 'Action to deny'), 'default' => 'all') - ) + ) + ))->addSubcommand('check', array( + 'help' => __d('cake_console', 'Check the permissions between an ACO and ARO.'), + 'parser' => array( + 'description' => array( + __d('cake_console', 'Use this command to check ACL permissions.') + ), + 'arguments' => array( + 'aro' => array('help' => __d('cake_console', 'ARO to check.'), 'required' => true), + 'aco' => array('help' => __d('cake_console', 'ACO to check.'), 'required' => true), + 'action' => array('help' => __d('cake_console', 'Action to check'), 'default' => 'all') ) - ))->addSubcommand('inherit', array( - 'help' => __d('cake_console', 'Inherit an ARO\'s parent permissions.'), - 'parser' => array( - 'description' => array( - __d('cake_console', "Use this command to force a child ARO object to inherit its permissions settings from its parent.") - ), - 'arguments' => array( - 'aro' => array('help' => __d('cake_console', 'ARO to have permissions inherit.'), 'required' => true), - 'aco' => array('help' => __d('cake_console', 'ACO to inherit permissions on.'), 'required' => true), - 'action' => array('help' => __d('cake_console', 'Action to inherit'), 'default' => 'all') - ) + ) + ))->addSubcommand('grant', array( + 'help' => __d('cake_console', 'Grant an ARO permissions to an ACO.'), + 'parser' => array( + 'description' => array( + __d('cake_console', 'Use this command to grant ACL permissions. Once executed, the ARO specified (and its children, if any) will have ALLOW access to the specified ACO action (and the ACO\'s children, if any).') + ), + 'arguments' => array( + 'aro' => array('help' => __d('cake_console', 'ARO to grant permission to.'), 'required' => true), + 'aco' => array('help' => __d('cake_console', 'ACO to grant access to.'), 'required' => true), + 'action' => array('help' => __d('cake_console', 'Action to grant'), 'default' => 'all') ) - ))->addSubcommand('view', array( - 'help' => __d('cake_console', 'View a tree or a single node\'s subtree.'), - 'parser' => array( - 'description' => array( - __d('cake_console', "The view command will return the ARO or ACO tree."), - __d('cake_console', "The optional node parameter allows you to return"), - __d('cake_console', "only a portion of the requested tree.") - ), - 'arguments' => array( - 'type' => $type, - 'node' => array('help' => __d('cake_console', 'The optional node to view the subtree of.')) - ) + ) + ))->addSubcommand('deny', array( + 'help' => __d('cake_console', 'Deny an ARO permissions to an ACO.'), + 'parser' => array( + 'description' => array( + __d('cake_console', 'Use this command to deny ACL permissions. Once executed, the ARO specified (and its children, if any) will have DENY access to the specified ACO action (and the ACO\'s children, if any).') + ), + 'arguments' => array( + 'aro' => array('help' => __d('cake_console', 'ARO to deny.'), 'required' => true), + 'aco' => array('help' => __d('cake_console', 'ACO to deny.'), 'required' => true), + 'action' => array('help' => __d('cake_console', 'Action to deny'), 'default' => 'all') ) - ))->addSubcommand('initdb', array( - 'help' => __d('cake_console', 'Initialize the DbAcl tables. Uses this command : cake schema create DbAcl') - ))->epilog( - array( - 'Node and parent arguments can be in one of the following formats:', - '', - ' - . - The node will be bound to a specific record of the given model.', - '', - ' - - The node will be given a string alias (or path, in the case of )', - " i.e. 'John'. When used with , this takes the form of an alias path,", - " i.e. //.", - '', - "To add a node at the root level, enter 'root' or '/' as the parameter." + ) + ))->addSubcommand('inherit', array( + 'help' => __d('cake_console', 'Inherit an ARO\'s parent permissions.'), + 'parser' => array( + 'description' => array( + __d('cake_console', "Use this command to force a child ARO object to inherit its permissions settings from its parent.") + ), + 'arguments' => array( + 'aro' => array('help' => __d('cake_console', 'ARO to have permissions inherit.'), 'required' => true), + 'aco' => array('help' => __d('cake_console', 'ACO to inherit permissions on.'), 'required' => true), + 'action' => array('help' => __d('cake_console', 'Action to inherit'), 'default' => 'all') ) - ); + ) + ))->addSubcommand('view', array( + 'help' => __d('cake_console', 'View a tree or a single node\'s subtree.'), + 'parser' => array( + 'description' => array( + __d('cake_console', "The view command will return the ARO or ACO tree."), + __d('cake_console', "The optional node parameter allows you to return"), + __d('cake_console', "only a portion of the requested tree.") + ), + 'arguments' => array( + 'type' => $type, + 'node' => array('help' => __d('cake_console', 'The optional node to view the subtree of.')) + ) + ) + ))->addSubcommand('initdb', array( + 'help' => __d('cake_console', 'Initialize the DbAcl tables. Uses this command : cake schema create DbAcl') + ))->epilog(array( + 'Node and parent arguments can be in one of the following formats:', + '', + ' - . - The node will be bound to a specific record of the given model.', + '', + ' - - The node will be given a string alias (or path, in the case of )', + " i.e. 'John'. When used with , this takes the form of an alias path,", + " i.e. //.", + '', + "To add a node at the root level, enter 'root' or '/' as the parameter." + )); + return $parser; } /** * Checks that given node exists * - * @return boolean Success + * @return bool Success */ public function nodeExists() { if (!isset($this->args[0]) || !isset($this->args[1])) { @@ -552,8 +558,8 @@ class AclShell extends AppShell { * or an array of properties to use in AcoNode::node() * * @param string $class Class type you want (Aro/Aco) - * @param string|array $identifier A mixed identifier for finding the node. - * @return integer Integer of NodeId. Will trigger an error if nothing is found. + * @param string|array|null $identifier A mixed identifier for finding the node, otherwise null. + * @return int Integer of NodeId. Will trigger an error if nothing is found. */ protected function _getNodeId($class, $identifier) { $node = $this->Acl->{$class}->node($identifier); @@ -562,7 +568,7 @@ class AclShell extends AppShell { $identifier = var_export($identifier, true); } $this->error(__d('cake_console', 'Could not find node using reference "%s"', $identifier)); - return; + return null; } return Hash::get($node, "0.{$class}.id"); } @@ -573,8 +579,8 @@ class AclShell extends AppShell { * @return array aro, aco, action */ protected function _getParams() { - $aro = is_numeric($this->args[0]) ? intval($this->args[0]) : $this->args[0]; - $aco = is_numeric($this->args[1]) ? intval($this->args[1]) : $this->args[1]; + $aro = is_numeric($this->args[0]) ? (int)$this->args[0] : $this->args[0]; + $aco = is_numeric($this->args[1]) ? (int)$this->args[1] : $this->args[1]; $aroName = $aro; $acoName = $aco; @@ -598,12 +604,12 @@ class AclShell extends AppShell { * @return array Variables */ protected function _dataVars($type = null) { - if ($type == null) { + if (!$type) { $type = $this->args[0]; } $vars = array(); $class = ucwords($type); - $vars['secondary_id'] = (strtolower($class) == 'aro') ? 'foreign_key' : 'object_id'; + $vars['secondary_id'] = (strtolower($class) === 'aro') ? 'foreign_key' : 'object_id'; $vars['data_name'] = $type; $vars['table_name'] = $type . 's'; $vars['class'] = $class; diff --git a/lib/Cake/Console/Command/ApiShell.php b/lib/Cake/Console/Command/ApiShell.php index 8ba50e7..8b0c979 100644 --- a/lib/Cake/Console/Command/ApiShell.php +++ b/lib/Cake/Console/Command/ApiShell.php @@ -4,18 +4,17 @@ * * Implementation of a Cake Shell to show CakePHP core method signatures. * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @since CakePHP(tm) v 1.2.0.5012 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ App::uses('AppShell', 'Console/Command'); @@ -73,12 +72,13 @@ class ApiShell extends AppShell { $path = $this->paths['core']; } - if (count($this->args) == 1) { - $file = $type; - $class = Inflector::camelize($type); - } elseif (count($this->args) > 1) { + $count = count($this->args); + if ($count > 1) { $file = Inflector::underscore($this->args[1]); $class = Inflector::camelize($this->args[1]); + } elseif ($count) { + $file = $type; + $class = Inflector::camelize($type); } $objects = App::objects('class', $path); if (in_array($class, $objects)) { @@ -98,7 +98,7 @@ class ApiShell extends AppShell { if (isset($this->params['method'])) { if (!isset($parsed[$this->params['method']])) { $this->err(__d('cake_console', '%s::%s() could not be found', $class, $this->params['method'])); - $this->_stop(); + return $this->_stop(); } $method = $parsed[$this->params['method']]; $this->out($class . '::' . $method['method'] . $method['parameters']); @@ -137,20 +137,24 @@ class ApiShell extends AppShell { } /** - * Get and configure the optionparser. + * Gets the option parser instance and configures it. * * @return ConsoleOptionParser */ public function getOptionParser() { $parser = parent::getOptionParser(); - $parser->addArgument('type', array( + + $parser->description( + __d('cake_console', 'Lookup doc block comments for classes in CakePHP.') + )->addArgument('type', array( 'help' => __d('cake_console', 'Either a full path or type of class (model, behavior, controller, component, view, helper)') ))->addArgument('className', array( 'help' => __d('cake_console', 'A CakePHP core class name (e.g: Component, HtmlHelper).') ))->addOption('method', array( 'short' => 'm', 'help' => __d('cake_console', 'The specific method you want help on.') - ))->description(__d('cake_console', 'Lookup doc block comments for classes in CakePHP.')); + )); + return $parser; } @@ -160,7 +164,7 @@ class ApiShell extends AppShell { * @return void */ public function help() { - $head = "Usage: cake api [] [-m ]\n"; + $head = "Usage: cake api [] [-m ]\n"; $head .= "-----------------------------------------------\n"; $head .= "Parameters:\n\n"; diff --git a/lib/Cake/Console/Command/AppShell.php b/lib/Cake/Console/Command/AppShell.php index 5cc915f..4ea0f2d 100644 --- a/lib/Cake/Console/Command/AppShell.php +++ b/lib/Cake/Console/Command/AppShell.php @@ -2,18 +2,17 @@ /** * AppShell file * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @since CakePHP(tm) v 2.0 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ App::uses('Shell', 'Console'); diff --git a/lib/Cake/Console/Command/BakeShell.php b/lib/Cake/Console/Command/BakeShell.php index 853074c..c1e59c6 100644 --- a/lib/Cake/Console/Command/BakeShell.php +++ b/lib/Cake/Console/Command/BakeShell.php @@ -6,18 +6,17 @@ * application development by writing fully functional skeleton controllers, * models, and views. Going further, Bake can also write Unit Tests for you. * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @since CakePHP(tm) v 1.2.0.5012 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ App::uses('AppShell', 'Console/Command'); @@ -65,6 +64,9 @@ class BakeShell extends AppShell { $this->{$task}->connection = $this->params['connection']; } } + if (isset($this->params['connection'])) { + $this->connection = $this->params['connection']; + } } /** @@ -122,8 +124,7 @@ class BakeShell extends AppShell { $this->Test->execute(); break; case 'Q': - exit(0); - break; + return $this->_stop(); default: $this->out(__d('cake_console', 'You have made an invalid selection. Please choose a type of class to Bake by entering D, M, V, F, T, or C.')); } @@ -202,18 +203,19 @@ class BakeShell extends AppShell { } /** - * get the option parser. + * Gets the option parser instance and configures it. * - * @return void + * @return ConsoleOptionParser */ public function getOptionParser() { $parser = parent::getOptionParser(); - return $parser->description(__d('cake_console', - 'The Bake script generates controllers, views and models for your application.' . + + $parser->description( + __d('cake_console', 'The Bake script generates controllers, views and models for your application.' . ' If run with no command line arguments, Bake guides the user through the class creation process.' . - ' You can customize the generation process by telling Bake where different parts of your application are using command line arguments.' - ))->addSubcommand('all', array( - 'help' => __d('cake_console', 'Bake a complete MVC. optional of a Model'), + ' You can customize the generation process by telling Bake where different parts of your application are using command line arguments.') + )->addSubcommand('all', array( + 'help' => __d('cake_console', 'Bake a complete MVC. optional of a Model') ))->addSubcommand('project', array( 'help' => __d('cake_console', 'Bake a new app folder in the path supplied or in current directory if no path is specified'), 'parser' => $this->Project->getOptionParser() @@ -242,7 +244,12 @@ class BakeShell extends AppShell { 'help' => __d('cake_console', 'Database connection to use in conjunction with `bake all`.'), 'short' => 'c', 'default' => 'default' + ))->addOption('theme', array( + 'short' => 't', + 'help' => __d('cake_console', 'Theme to use when baking code.') )); + + return $parser; } } diff --git a/lib/Cake/Console/Command/CommandListShell.php b/lib/Cake/Console/Command/CommandListShell.php index 512349c..9ea4496 100644 --- a/lib/Cake/Console/Command/CommandListShell.php +++ b/lib/Cake/Console/Command/CommandListShell.php @@ -1,16 +1,17 @@ out(" -working: " . rtrim(APP, DS)); $this->out(" -root: " . rtrim(ROOT, DS)); $this->out(" -core: " . rtrim(CORE_PATH, DS)); + $this->out(" -webroot: " . rtrim(WWW_ROOT, DS)); $this->out(""); $this->out(__d('cake_console', "Changing Paths:"), 2); - $this->out(__d('cake_console', "Your working path should be the same as your application path to change your path use the '-app' param.")); - $this->out(__d('cake_console', "Example: -app relative/path/to/myapp or -app /absolute/path/to/myapp"), 2); + $this->out(__d('cake_console', "Your working path should be the same as your application path. To change your path use the '-app' param.")); + $this->out(__d('cake_console', "Example: %s or %s", '-app relative/path/to/myapp', '-app /absolute/path/to/myapp'), 2); $this->out(__d('cake_console', "Available Shells:"), 2); } - $shellList = $this->_getShellList(); + $shellList = $this->Command->getShellList(); if (empty($shellList)) { return; } @@ -66,52 +75,10 @@ class CommandListShell extends AppShell { } } -/** - * Gets the shell command listing. - * - * @return array - */ - protected function _getShellList() { - $skipFiles = array('AppShell'); - - $plugins = CakePlugin::loaded(); - $shellList = array_fill_keys($plugins, null) + array('CORE' => null, 'app' => null); - - $corePath = App::core('Console/Command'); - $shells = App::objects('file', $corePath[0]); - $shells = array_diff($shells, $skipFiles); - $this->_appendShells('CORE', $shells, $shellList); - - $appShells = App::objects('Console/Command', null, false); - $appShells = array_diff($appShells, $shells, $skipFiles); - $this->_appendShells('app', $appShells, $shellList); - - foreach ($plugins as $plugin) { - $pluginShells = App::objects($plugin . '.Console/Command'); - $this->_appendShells($plugin, $pluginShells, $shellList); - } - - return array_filter($shellList); - } - -/** - * Scan the provided paths for shells, and append them into $shellList - * - * @param string $type - * @param array $shells - * @param array $shellList - * @return array - */ - protected function _appendShells($type, $shells, &$shellList) { - foreach ($shells as $shell) { - $shellList[$type][] = Inflector::underscore(str_replace('Shell', '', $shell)); - } - } - /** * Output text. * - * @param array $shellList + * @param array $shellList The shell list. * @return void */ protected function _asText($shellList) { @@ -129,7 +96,7 @@ class CommandListShell extends AppShell { /** * Output as XML * - * @param array $shellList + * @param array $shellList The shell list. * @return void */ protected function _asXml($shellList) { @@ -154,21 +121,24 @@ class CommandListShell extends AppShell { } /** - * get the option parser + * Gets the option parser instance and configures it. * - * @return void + * @return ConsoleOptionParser */ public function getOptionParser() { $parser = parent::getOptionParser(); - return $parser->description(__d('cake_console', 'Get the list of available shells for this CakePHP application.')) - ->addOption('sort', array( - 'help' => __d('cake_console', 'Does nothing (deprecated)'), - 'boolean' => true - )) - ->addOption('xml', array( - 'help' => __d('cake_console', 'Get the listing as XML.'), - 'boolean' => true - )); + + $parser->description( + __d('cake_console', 'Get the list of available shells for this CakePHP application.') + )->addOption('sort', array( + 'help' => __d('cake_console', 'Does nothing (deprecated)'), + 'boolean' => true + ))->addOption('xml', array( + 'help' => __d('cake_console', 'Get the listing as XML.'), + 'boolean' => true + )); + + return $parser; } } diff --git a/lib/Cake/Console/Command/CompletionShell.php b/lib/Cake/Console/Command/CompletionShell.php new file mode 100644 index 0000000..57e86f9 --- /dev/null +++ b/lib/Cake/Console/Command/CompletionShell.php @@ -0,0 +1,155 @@ +out($this->getOptionParser()->help()); + } + +/** + * list commands + * + * @return void + */ + public function commands() { + $options = $this->Command->commands(); + return $this->_output($options); + } + +/** + * list options for the named command + * + * @return void + */ + public function options() { + $commandName = ''; + if (!empty($this->args[0])) { + $commandName = $this->args[0]; + } + $options = $this->Command->options($commandName); + + return $this->_output($options); + } + +/** + * list subcommands for the named command + * + * @return void + */ + public function subCommands() { + if (!$this->args) { + return $this->_output(); + } + + $options = $this->Command->subCommands($this->args[0]); + return $this->_output($options); + } + +/** + * Guess autocomplete from the whole argument string + * + * @return void + */ + public function fuzzy() { + return $this->_output(); + } + +/** + * Gets the option parser instance and configures it. + * + * @return ConsoleOptionParser + */ + public function getOptionParser() { + $parser = parent::getOptionParser(); + + $parser->description( + __d('cake_console', 'Used by shells like bash to autocomplete command name, options and arguments') + )->addSubcommand('commands', array( + 'help' => __d('cake_console', 'Output a list of available commands'), + 'parser' => array( + 'description' => __d('cake_console', 'List all availables'), + 'arguments' => array( + ) + ) + ))->addSubcommand('subcommands', array( + 'help' => __d('cake_console', 'Output a list of available subcommands'), + 'parser' => array( + 'description' => __d('cake_console', 'List subcommands for a command'), + 'arguments' => array( + 'command' => array( + 'help' => __d('cake_console', 'The command name'), + 'required' => true, + ) + ) + ) + ))->addSubcommand('options', array( + 'help' => __d('cake_console', 'Output a list of available options'), + 'parser' => array( + 'description' => __d('cake_console', 'List options'), + 'arguments' => array( + 'command' => array( + 'help' => __d('cake_console', 'The command name'), + 'required' => false, + ) + ) + ) + ))->epilog( + __d('cake_console', 'This command is not intended to be called manually') + ); + + return $parser; + } + +/** + * Emit results as a string, space delimited + * + * @param array $options The options to output + * @return void + */ + protected function _output($options = array()) { + if ($options) { + return $this->out(implode($options, ' ')); + } + } +} diff --git a/lib/Cake/Console/Command/ConsoleShell.php b/lib/Cake/Console/Command/ConsoleShell.php index 31736bb..ac270e1 100644 --- a/lib/Cake/Console/Command/ConsoleShell.php +++ b/lib/Cake/Console/Command/ConsoleShell.php @@ -1,15 +1,16 @@ '/^(help|\?)/', + '_exit' => '/^(quit|exit)/', + '_models' => '/^models/i', + '_bind' => '/^(\w+) bind (\w+) (\w+)/', + '_unbind' => '/^(\w+) unbind (\w+) (\w+)/', + '_find' => '/.+->find/', + '_save' => '/.+->save/', + '_columns' => '/^(\w+) columns/', + '_routesReload' => '/^routes\s+reload/i', + '_routesShow' => '/^routes\s+show/i', + '_routeToString' => '/^route\s+(\(.*\))$/i', + '_routeToArray' => '/^route\s+(.*)$/i', + ); + /** * Override startup of the Shell * @@ -54,7 +85,6 @@ class ConsoleShell extends AppShell { foreach ($this->models as $model) { $class = $model; - $this->models[$model] = $class; App::uses($class, 'Model'); $this->{$class} = new $class(); } @@ -74,15 +104,20 @@ class ConsoleShell extends AppShell { } } +/** + * Gets the option parser instance and configures it. + * + * @return ConsoleOptionParser + */ public function getOptionParser() { - $description = array( + $parser = parent::getOptionParser(); + + $parser->description(array( 'The interactive console is a tool for testing parts of your', 'app before you write code.', '', 'See below for a list of supported commands.' - ); - - $epilog = array( + ))->epilog(array( 'Model testing', '', 'To test model results, use the name of your model without a leading $', @@ -120,7 +155,7 @@ class ConsoleShell extends AppShell { "\tRoute ", "", "where url is the path to your your action plus any query parameters,", - "minus the application's base path. For example:", + "minus the application's base path. For example:", "", "\tRoute /posts/view/1", "", @@ -141,10 +176,9 @@ class ConsoleShell extends AppShell { 'To show all connected routes, do the following:', '', "\tRoutes show", - ); - return parent::getOptionParser() - ->description($description) - ->epilog($epilog); + )); + + return $parser; } /** * Prints the help message @@ -159,202 +193,298 @@ class ConsoleShell extends AppShell { /** * Override main() to handle action * - * @param string $command + * @param string $command The command to run. * @return void */ public function main($command = null) { - while (true) { + $this->_finished = false; + while (!$this->_finished) { if (empty($command)) { $command = trim($this->in('')); } - switch ($command) { - case 'help': - $this->help(); - break; - case 'quit': - case 'exit': - return true; - case 'models': - $this->out(__d('cake_console', 'Model classes:')); - $this->hr(); - foreach ($this->models as $model) { - $this->out(" - {$model}"); - } - break; - case (preg_match("/^(\w+) bind (\w+) (\w+)/", $command, $tmp) == true): - foreach ($tmp as $data) { - $data = strip_tags($data); - $data = str_replace($this->badCommandChars, "", $data); - } + $method = $this->_method($command); - $modelA = $tmp[1]; - $association = $tmp[2]; - $modelB = $tmp[3]; - - if ($this->_isValidModel($modelA) && $this->_isValidModel($modelB) && in_array($association, $this->associations)) { - $this->{$modelA}->bindModel(array($association => array($modelB => array('className' => $modelB))), false); - $this->out(__d('cake_console', "Created %s association between %s and %s", - $association, $modelA, $modelB)); - } else { - $this->out(__d('cake_console', "Please verify you are using valid models and association types")); - } - break; - case (preg_match("/^(\w+) unbind (\w+) (\w+)/", $command, $tmp) == true): - foreach ($tmp as $data) { - $data = strip_tags($data); - $data = str_replace($this->badCommandChars, "", $data); - } - - $modelA = $tmp[1]; - $association = $tmp[2]; - $modelB = $tmp[3]; - - // Verify that there is actually an association to unbind - $currentAssociations = $this->{$modelA}->getAssociated(); - $validCurrentAssociation = false; - - foreach ($currentAssociations as $model => $currentAssociation) { - if ($model == $modelB && $association == $currentAssociation) { - $validCurrentAssociation = true; - } - } - - if ($this->_isValidModel($modelA) && $this->_isValidModel($modelB) && in_array($association, $this->associations) && $validCurrentAssociation) { - $this->{$modelA}->unbindModel(array($association => array($modelB))); - $this->out(__d('cake_console', "Removed %s association between %s and %s", - $association, $modelA, $modelB)); - } else { - $this->out(__d('cake_console', "Please verify you are using valid models, valid current association, and valid association types")); - } - break; - case (strpos($command, "->find") > 0): - // Remove any bad info - $command = strip_tags($command); - $command = str_replace($this->badCommandChars, "", $command); - - // Do we have a valid model? - list($modelToCheck, $tmp) = explode('->', $command); - - if ($this->_isValidModel($modelToCheck)) { - $findCommand = "\$data = \$this->$command;"; - //@codingStandardsIgnoreStart - @eval($findCommand); - //@codingStandardsIgnoreEnd - - if (is_array($data)) { - foreach ($data as $idx => $results) { - if (is_numeric($idx)) { // findAll() output - foreach ($results as $modelName => $result) { - $this->out("$modelName"); - - foreach ($result as $field => $value) { - if (is_array($value)) { - foreach ($value as $field2 => $value2) { - $this->out("\t$field2: $value2"); - } - - $this->out(); - } else { - $this->out("\t$field: $value"); - } - } - } - } else { // find() output - $this->out($idx); - - foreach ($results as $field => $value) { - if (is_array($value)) { - foreach ($value as $field2 => $value2) { - $this->out("\t$field2: $value2"); - } - - $this->out(); - } else { - $this->out("\t$field: $value"); - } - } - } - } - } else { - $this->out(); - $this->out(__d('cake_console', "No result set found")); - } - } else { - $this->out(__d('cake_console', "%s is not a valid model", $modelToCheck)); - } - - break; - case (strpos($command, '->save') > 0): - // Validate the model we're trying to save here - $command = strip_tags($command); - $command = str_replace($this->badCommandChars, "", $command); - list($modelToSave, $tmp) = explode("->", $command); - - if ($this->_isValidModel($modelToSave)) { - // Extract the array of data we are trying to build - list($foo, $data) = explode("->save", $command); - $data = preg_replace('/^\(*(array)?\(*(.+?)\)*$/i', '\\2', $data); - $saveCommand = "\$this->{$modelToSave}->save(array('{$modelToSave}' => array({$data})));"; - //@codingStandardsIgnoreStart - @eval($saveCommand); - //@codingStandardsIgnoreEnd - $this->out(__d('cake_console', 'Saved record for %s', $modelToSave)); - } - break; - case (preg_match("/^(\w+) columns/", $command, $tmp) == true): - $modelToCheck = strip_tags(str_replace($this->badCommandChars, "", $tmp[1])); - - if ($this->_isValidModel($modelToCheck)) { - // Get the column info for this model - $fieldsCommand = "\$data = \$this->{$modelToCheck}->getColumnTypes();"; - //@codingStandardsIgnoreStart - @eval($fieldsCommand); - //@codingStandardsIgnoreEnd - - if (is_array($data)) { - foreach ($data as $field => $type) { - $this->out("\t{$field}: {$type}"); - } - } - } else { - $this->out(__d('cake_console', "Please verify that you selected a valid model")); - } - break; - case (preg_match("/^routes\s+reload/i", $command, $tmp) == true): - if (!$this->_loadRoutes()) { - $this->err(__d('cake_console', "There was an error loading the routes config. Please check that the file exists and is free of parse errors.")); - break; - } - $this->out(__d('cake_console', "Routes configuration reloaded, %d routes connected", count(Router::$routes))); - break; - case (preg_match("/^routes\s+show/i", $command, $tmp) == true): - $this->out(print_r(Hash::combine(Router::$routes, '{n}.template', '{n}.defaults'), true)); - break; - case (preg_match("/^route\s+(\(.*\))$/i", $command, $tmp) == true): - //@codingStandardsIgnoreStart - if ($url = eval('return array' . $tmp[1] . ';')) { - //@codingStandardsIgnoreEnd - $this->out(Router::url($url)); - } - break; - case (preg_match("/^route\s+(.*)/i", $command, $tmp) == true): - $this->out(var_export(Router::parse($tmp[1]), true)); - break; - default: - $this->out(__d('cake_console', "Invalid command")); - $this->out(); - break; + if ($method) { + $this->$method($command); + } else { + $this->out(__d('cake_console', "Invalid command")); + $this->out(); } $command = ''; } } +/** + * Determine the method to process the current command + * + * @param string $command The command to run. + * @return string or false + */ + protected function _method($command) { + foreach ($this->_methodPatterns as $method => $pattern) { + if (preg_match($pattern, $command)) { + return $method; + } + } + + return false; + } + +/** + * Set the finiished property so that the loop in main method ends + * + * @return void + */ + protected function _exit() { + $this->_finished = true; + } + +/** + * List all models + * + * @return void + */ + protected function _models() { + $this->out(__d('cake_console', 'Model classes:')); + $this->hr(); + foreach ($this->models as $model) { + $this->out(" - {$model}"); + } + } + +/** + * Bind an association + * + * @param mixed $command The command to run. + * @return void + */ + protected function _bind($command) { + preg_match($this->_methodPatterns[__FUNCTION__], $command, $tmp); + + foreach ($tmp as $data) { + $data = strip_tags($data); + $data = str_replace($this->badCommandChars, "", $data); + } + + $modelA = $tmp[1]; + $association = $tmp[2]; + $modelB = $tmp[3]; + + if ($this->_isValidModel($modelA) && $this->_isValidModel($modelB) && in_array($association, $this->associations)) { + $this->{$modelA}->bindModel(array($association => array($modelB => array('className' => $modelB))), false); + $this->out(__d('cake_console', "Created %s association between %s and %s", + $association, $modelA, $modelB)); + } else { + $this->out(__d('cake_console', "Please verify you are using valid models and association types")); + } + } + +/** + * Unbind an association + * + * @param mixed $command The command to run. + * @return void + */ + protected function _unbind($command) { + preg_match($this->_methodPatterns[__FUNCTION__], $command, $tmp); + + foreach ($tmp as $data) { + $data = strip_tags($data); + $data = str_replace($this->badCommandChars, "", $data); + } + + $modelA = $tmp[1]; + $association = $tmp[2]; + $modelB = $tmp[3]; + + // Verify that there is actually an association to unbind + $currentAssociations = $this->{$modelA}->getAssociated(); + $validCurrentAssociation = false; + + foreach ($currentAssociations as $model => $currentAssociation) { + if ($model === $modelB && $association === $currentAssociation) { + $validCurrentAssociation = true; + } + } + + if ($this->_isValidModel($modelA) && $this->_isValidModel($modelB) && in_array($association, $this->associations) && $validCurrentAssociation) { + $this->{$modelA}->unbindModel(array($association => array($modelB))); + $this->out(__d('cake_console', "Removed %s association between %s and %s", + $association, $modelA, $modelB)); + } else { + $this->out(__d('cake_console', "Please verify you are using valid models, valid current association, and valid association types")); + } + } + +/** + * Perform a find + * + * @param mixed $command The command to run. + * @return void + */ + protected function _find($command) { + $command = strip_tags($command); + $command = str_replace($this->badCommandChars, "", $command); + + // Do we have a valid model? + list($modelToCheck) = explode('->', $command); + + if ($this->_isValidModel($modelToCheck)) { + $findCommand = "\$data = \$this->$command;"; + //@codingStandardsIgnoreStart + @eval($findCommand); + //@codingStandardsIgnoreEnd + + if (is_array($data)) { + foreach ($data as $idx => $results) { + if (is_numeric($idx)) { // findAll() output + foreach ($results as $modelName => $result) { + $this->out("$modelName"); + + foreach ($result as $field => $value) { + if (is_array($value)) { + foreach ($value as $field2 => $value2) { + $this->out("\t$field2: $value2"); + } + + $this->out(); + } else { + $this->out("\t$field: $value"); + } + } + } + } else { // find() output + $this->out($idx); + + foreach ($results as $field => $value) { + if (is_array($value)) { + foreach ($value as $field2 => $value2) { + $this->out("\t$field2: $value2"); + } + + $this->out(); + } else { + $this->out("\t$field: $value"); + } + } + } + } + } else { + $this->out(); + $this->out(__d('cake_console', "No result set found")); + } + } else { + $this->out(__d('cake_console', "%s is not a valid model", $modelToCheck)); + } + } + +/** + * Save a record + * + * @param mixed $command The command to run. + * @return void + */ + protected function _save($command) { + // Validate the model we're trying to save here + $command = strip_tags($command); + $command = str_replace($this->badCommandChars, "", $command); + list($modelToSave) = explode("->", $command); + + if ($this->_isValidModel($modelToSave)) { + // Extract the array of data we are trying to build + list(, $data) = explode("->save", $command); + $data = preg_replace('/^\(*(array)?\(*(.+?)\)*$/i', '\\2', $data); + $saveCommand = "\$this->{$modelToSave}->save(array('{$modelToSave}' => array({$data})));"; + //@codingStandardsIgnoreStart + @eval($saveCommand); + //@codingStandardsIgnoreEnd + $this->out(__d('cake_console', 'Saved record for %s', $modelToSave)); + } + } + +/** + * Show the columns for a model + * + * @param mixed $command The command to run. + * @return void + */ + protected function _columns($command) { + preg_match($this->_methodPatterns[__FUNCTION__], $command, $tmp); + + $modelToCheck = strip_tags(str_replace($this->badCommandChars, "", $tmp[1])); + + if ($this->_isValidModel($modelToCheck)) { + // Get the column info for this model + $fieldsCommand = "\$data = \$this->{$modelToCheck}->getColumnTypes();"; + //@codingStandardsIgnoreStart + @eval($fieldsCommand); + //@codingStandardsIgnoreEnd + + if (is_array($data)) { + foreach ($data as $field => $type) { + $this->out("\t{$field}: {$type}"); + } + } + } else { + $this->out(__d('cake_console', "Please verify that you selected a valid model")); + } + } + +/** + * Reload route definitions + * + * @return void + */ + protected function _routesReload() { + if (!$this->_loadRoutes()) { + return $this->err(__d('cake_console', "There was an error loading the routes config. Please check that the file exists and is free of parse errors.")); + } + $this->out(__d('cake_console', "Routes configuration reloaded, %d routes connected", count(Router::$routes))); + } + +/** + * Show all routes + * + * @return void + */ + protected function _routesShow() { + $this->out(print_r(Hash::combine(Router::$routes, '{n}.template', '{n}.defaults'), true)); + } + +/** + * Parse an array URL and show the equivalent URL as a string + * + * @param mixed $command The command to run. + * @return void + */ + protected function _routeToString($command) { + preg_match($this->_methodPatterns[__FUNCTION__], $command, $tmp); + + //@codingStandardsIgnoreStart + if ($url = eval('return array' . $tmp[1] . ';')) { + //@codingStandardsIgnoreEnd + $this->out(Router::url($url)); + } + } + +/** + * Parse a string URL and show as an array + * + * @param mixed $command The command to run. + * @return void + */ + protected function _routeToArray($command) { + preg_match($this->_methodPatterns[__FUNCTION__], $command, $tmp); + + $this->out(var_export(Router::parse($tmp[1]), true)); + } + /** * Tells if the specified model is included in the list of available models * - * @param string $modelToCheck - * @return boolean true if is an available model, false otherwise + * @param string $modelToCheck The model to check. + * @return bool true if is an available model, false otherwise */ protected function _isValidModel($modelToCheck) { return in_array($modelToCheck, $this->models); @@ -364,7 +494,7 @@ class ConsoleShell extends AppShell { * Reloads the routes configuration from app/Config/routes.php, and compiles * all routes found * - * @return boolean True if config reload was a success, otherwise false + * @return bool True if config reload was a success, otherwise false */ protected function _loadRoutes() { Router::reload(); diff --git a/lib/Cake/Console/Command/I18nShell.php b/lib/Cake/Console/Command/I18nShell.php index 73e67a2..c87ce69 100644 --- a/lib/Cake/Console/Command/I18nShell.php +++ b/lib/Cake/Console/Command/I18nShell.php @@ -2,18 +2,17 @@ /** * Internationalization Management Shell * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @since CakePHP(tm) v 1.2.0.5669 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ App::uses('AppShell', 'Console/Command'); @@ -52,7 +51,7 @@ class I18nShell extends AppShell { if ($this->command && !in_array($this->command, array('help'))) { if (!config('database')) { - $this->out(__d('cake_console', 'Your database configuration was not found. Take a moment to create one.'), true); + $this->out(__d('cake_console', 'Your database configuration was not found. Take a moment to create one.')); return $this->DbConfig->execute(); } } @@ -75,16 +74,15 @@ class I18nShell extends AppShell { switch ($choice) { case 'e': $this->Extract->execute(); - break; + break; case 'i': $this->initdb(); - break; + break; case 'h': $this->out($this->OptionParser->help()); - break; + break; case 'q': - exit(0); - break; + return $this->_stop(); default: $this->out(__d('cake_console', 'You have made an invalid selection. Please choose a command to execute by entering E, I, H, or Q.')); } @@ -102,20 +100,23 @@ class I18nShell extends AppShell { } /** - * Get and configure the Option parser + * Gets the option parser instance and configures it. * * @return ConsoleOptionParser */ public function getOptionParser() { $parser = parent::getOptionParser(); - return $parser->description( + + $parser->description( __d('cake_console', 'I18n Shell initializes i18n database table for your application and generates .pot files(s) with translations.') - )->addSubcommand('initdb', array( - 'help' => __d('cake_console', 'Initialize the i18n table.') - ))->addSubcommand('extract', array( - 'help' => __d('cake_console', 'Extract the po translations from your application'), - 'parser' => $this->Extract->getOptionParser() - )); + )->addSubcommand('initdb', array( + 'help' => __d('cake_console', 'Initialize the i18n table.') + ))->addSubcommand('extract', array( + 'help' => __d('cake_console', 'Extract the po translations from your application'), + 'parser' => $this->Extract->getOptionParser() + )); + + return $parser; } } diff --git a/lib/Cake/Console/Command/SchemaShell.php b/lib/Cake/Console/Command/SchemaShell.php index 8cb9510..a2ddfcc 100644 --- a/lib/Cake/Console/Command/SchemaShell.php +++ b/lib/Cake/Console/Command/SchemaShell.php @@ -1,15 +1,16 @@ out('Cake Schema Shell'); $this->hr(); + Configure::write('Cache.disable', 1); + $name = $path = $connection = $plugin = null; if (!empty($this->params['name'])) { $name = $this->params['name']; @@ -63,12 +66,9 @@ class SchemaShell extends AppShell { list($this->params['plugin'], $splitName) = pluginSplit($name); $name = $this->params['name'] = $splitName; } - - if ($name) { + if ($name && empty($this->params['file'])) { $this->params['file'] = Inflector::underscore($name); - } - - if (empty($this->params['file'])) { + } elseif (empty($this->params['file'])) { $this->params['file'] = 'schema.php'; } if (strpos($this->params['file'], '.php') === false) { @@ -89,6 +89,7 @@ class SchemaShell extends AppShell { $name = $plugin; } } + $name = Inflector::camelize($name); $this->Schema = new CakeSchema(compact('name', 'path', 'file', 'connection', 'plugin')); } @@ -102,12 +103,11 @@ class SchemaShell extends AppShell { $File = new File($this->Schema->path . DS . $this->params['file']); if ($File->exists()) { $this->out($File->read()); - $this->_stop(); - } else { - $file = $this->Schema->path . DS . $this->params['file']; - $this->err(__d('cake_console', 'Schema file (%s) could not be found.', $file)); - $this->_stop(); + return $this->_stop(); } + $file = $this->Schema->path . DS . $this->params['file']; + $this->err(__d('cake_console', 'Schema file (%s) could not be found.', $file)); + return $this->_stop(); } /** @@ -120,7 +120,9 @@ class SchemaShell extends AppShell { $this->out(__d('cake_console', 'Generating Schema...')); $options = array(); if ($this->params['force']) { - $options = array('models' => false); + $options['models'] = false; + } elseif (!empty($this->params['models'])) { + $options['models'] = CakeText::tokenize($this->params['models']); } $snapshot = false; @@ -148,8 +150,15 @@ class SchemaShell extends AppShell { Configure::write('Cache.disable', $cacheDisable); + if (!empty($this->params['exclude']) && !empty($content)) { + $excluded = CakeText::tokenize($this->params['exclude']); + foreach ($excluded as $table) { + unset($content['tables'][$table]); + } + } + if ($snapshot === true) { - $fileName = rtrim($this->params['file'], '.php'); + $fileName = basename($this->params['file'], '.php'); $Folder = new Folder($this->Schema->path); $result = $Folder->read(); @@ -178,11 +187,10 @@ class SchemaShell extends AppShell { if ($this->Schema->write($content)) { $this->out(__d('cake_console', 'Schema file: %s generated', $content['file'])); - $this->_stop(); - } else { - $this->err(__d('cake_console', 'Schema file: %s generated')); - $this->_stop(); + return $this->_stop(); } + $this->err(__d('cake_console', 'Schema file: %s generated')); + return $this->_stop(); } /** @@ -199,7 +207,7 @@ class SchemaShell extends AppShell { $Schema = $this->Schema->load(); if (!$Schema) { $this->err(__d('cake_console', 'Schema could not be loaded')); - $this->_stop(); + return $this->_stop(); } if (!empty($this->params['write'])) { if ($this->params['write'] == 1) { @@ -223,18 +231,17 @@ class SchemaShell extends AppShell { if ($File->write($contents)) { $this->out(__d('cake_console', 'SQL dump file created in %s', $File->pwd())); - $this->_stop(); - } else { - $this->err(__d('cake_console', 'SQL dump could not be created')); - $this->_stop(); + return $this->_stop(); } + $this->err(__d('cake_console', 'SQL dump could not be created')); + return $this->_stop(); } $this->out($contents); return $contents; } /** - * Run database create commands. Alias for run create. + * Run database create commands. Alias for run create. * * @return void */ @@ -244,7 +251,7 @@ class SchemaShell extends AppShell { } /** - * Run database create commands. Alias for run create. + * Run database create commands. Alias for run create. * * @return void */ @@ -272,19 +279,23 @@ class SchemaShell extends AppShell { $this->out(__d('cake_console', 'Performing a dry run.')); } - $options = array('name' => $name, 'plugin' => $plugin); + $options = array( + 'name' => $name, + 'plugin' => $plugin, + 'connection' => $this->params['connection'], + ); if (!empty($this->params['snapshot'])) { - $fileName = rtrim($this->Schema->file, '.php'); + $fileName = basename($this->Schema->file, '.php'); $options['file'] = $fileName . '_' . $this->params['snapshot'] . '.php'; } $Schema = $this->Schema->load($options); if (!$Schema) { - $this->err(__d('cake_console', 'The chosen schema could not be loaded. Attempted to load:')); - $this->err(__d('cake_console', 'File: %s', $this->Schema->path . DS . $this->Schema->file)); - $this->err(__d('cake_console', 'Name: %s', $this->Schema->name)); - $this->_stop(); + $this->err(__d('cake_console', 'Error: The chosen schema could not be loaded. Attempted to load:')); + $this->err(__d('cake_console', '- file: %s', $this->Schema->path . DS . $this->Schema->file)); + $this->err(__d('cake_console', '- name: %s', $this->Schema->name)); + return $this->_stop(2); } $table = null; if (isset($this->args[1])) { @@ -297,11 +308,11 @@ class SchemaShell extends AppShell { * Create database from Schema object * Should be called via the run method * - * @param CakeSchema $Schema - * @param string $table + * @param CakeSchema $Schema The schema instance to create. + * @param string $table The table name. * @return void */ - protected function _create($Schema, $table = null) { + protected function _create(CakeSchema $Schema, $table = null) { $db = ConnectionManager::getDataSource($this->Schema->connection); $drop = $create = array(); @@ -317,13 +328,15 @@ class SchemaShell extends AppShell { } if (empty($drop) || empty($create)) { $this->out(__d('cake_console', 'Schema is up to date.')); - $this->_stop(); + return $this->_stop(); } $this->out("\n" . __d('cake_console', 'The following table(s) will be dropped.')); $this->out(array_keys($drop)); - if ('y' == $this->in(__d('cake_console', 'Are you sure you want to drop the table(s)?'), array('y', 'n'), 'n')) { + if (!empty($this->params['yes']) || + $this->in(__d('cake_console', 'Are you sure you want to drop the table(s)?'), array('y', 'n'), 'n') === 'y' + ) { $this->out(__d('cake_console', 'Dropping table(s).')); $this->_run($drop, 'drop', $Schema); } @@ -331,7 +344,9 @@ class SchemaShell extends AppShell { $this->out("\n" . __d('cake_console', 'The following table(s) will be created.')); $this->out(array_keys($create)); - if ('y' == $this->in(__d('cake_console', 'Are you sure you want to create the table(s)?'), array('y', 'n'), 'y')) { + if (!empty($this->params['yes']) || + $this->in(__d('cake_console', 'Are you sure you want to create the table(s)?'), array('y', 'n'), 'y') === 'y' + ) { $this->out(__d('cake_console', 'Creating table(s).')); $this->_run($create, 'create', $Schema); } @@ -342,8 +357,8 @@ class SchemaShell extends AppShell { * Update database with Schema object * Should be called via the run method * - * @param CakeSchema $Schema - * @param string $table + * @param CakeSchema &$Schema The schema instance + * @param string $table The table name. * @return void */ protected function _update(&$Schema, $table = null) { @@ -361,23 +376,36 @@ class SchemaShell extends AppShell { if (empty($table)) { foreach ($compare as $table => $changes) { - $contents[$table] = $db->alterSchema(array($table => $changes), $table); + if (isset($compare[$table]['create'])) { + $contents[$table] = $db->createSchema($Schema, $table); + } else { + $contents[$table] = $db->alterSchema(array($table => $compare[$table]), $table); + } } } elseif (isset($compare[$table])) { - $contents[$table] = $db->alterSchema(array($table => $compare[$table]), $table); + if (isset($compare[$table]['create'])) { + $contents[$table] = $db->createSchema($Schema, $table); + } else { + $contents[$table] = $db->alterSchema(array($table => $compare[$table]), $table); + } } if (empty($contents)) { $this->out(__d('cake_console', 'Schema is up to date.')); - $this->_stop(); + return $this->_stop(); } $this->out("\n" . __d('cake_console', 'The following statements will run.')); $this->out(array_map('trim', $contents)); - if ('y' == $this->in(__d('cake_console', 'Are you sure you want to alter the tables?'), array('y', 'n'), 'n')) { + if (!empty($this->params['yes']) || + $this->in(__d('cake_console', 'Are you sure you want to alter the tables?'), array('y', 'n'), 'n') === 'y' + ) { $this->out(); $this->out(__d('cake_console', 'Updating Database...')); $this->_run($contents, 'update', $Schema); + + Configure::write('Cache.disable', false); + Cache::clear(false, '_cake_model_'); } $this->out(__d('cake_console', 'End update.')); @@ -386,12 +414,12 @@ class SchemaShell extends AppShell { /** * Runs sql from _create() or _update() * - * @param array $contents - * @param string $event - * @param CakeSchema $Schema + * @param array $contents The contents to execute. + * @param string $event The event to fire + * @param CakeSchema $Schema The schema instance. * @return void */ - protected function _run($contents, $event, &$Schema) { + protected function _run($contents, $event, CakeSchema $Schema) { if (empty($contents)) { $this->err(__d('cake_console', 'Sql could not be run')); return; @@ -430,11 +458,13 @@ class SchemaShell extends AppShell { } /** - * get the option parser + * Gets the option parser instance and configures it. * - * @return void + * @return ConsoleOptionParser */ public function getOptionParser() { + $parser = parent::getOptionParser(); + $plugin = array( 'short' => 'p', 'help' => __d('cake_console', 'The plugin to use.'), @@ -450,17 +480,24 @@ class SchemaShell extends AppShell { ); $file = array( 'help' => __d('cake_console', 'File name to read and write.'), - 'default' => 'schema.php' ); $name = array( - 'help' => __d('cake_console', 'Classname to use. If its Plugin.class, both name and plugin options will be set.') + 'help' => __d('cake_console', + 'Classname to use. If its Plugin.class, both name and plugin options will be set.' + ) ); $snapshot = array( 'short' => 's', 'help' => __d('cake_console', 'Snapshot number to use/make.') ); + $models = array( + 'short' => 'm', + 'help' => __d('cake_console', 'Specify models as comma separated list.'), + ); $dry = array( - 'help' => __d('cake_console', 'Perform a dry run on create and update commands. Queries will be output instead of run.'), + 'help' => __d('cake_console', + 'Perform a dry run on create and update commands. Queries will be output instead of run.' + ), 'boolean' => true ); $force = array( @@ -471,8 +508,15 @@ class SchemaShell extends AppShell { $write = array( 'help' => __d('cake_console', 'Write the dumped SQL to a file.') ); + $exclude = array( + 'help' => __d('cake_console', 'Tables to exclude as comma separated list.') + ); + $yes = array( + 'short' => 'y', + 'help' => __d('cake_console', 'Do not prompt for confirmation. Be careful!'), + 'boolean' => true + ); - $parser = parent::getOptionParser(); $parser->description( __d('cake_console', 'The Schema Shell generates a schema object from the database and updates the database from the schema.') )->addSubcommand('view', array( @@ -484,7 +528,7 @@ class SchemaShell extends AppShell { ))->addSubcommand('generate', array( 'help' => __d('cake_console', 'Reads from --connection and writes to --path. Generate snapshots with -s'), 'parser' => array( - 'options' => compact('plugin', 'path', 'file', 'name', 'connection', 'snapshot', 'force'), + 'options' => compact('plugin', 'path', 'file', 'name', 'connection', 'snapshot', 'force', 'models', 'exclude'), 'arguments' => array( 'snapshot' => array('help' => __d('cake_console', 'Generate a snapshot.')) ) @@ -498,7 +542,7 @@ class SchemaShell extends AppShell { ))->addSubcommand('create', array( 'help' => __d('cake_console', 'Drop and create tables based on the schema file.'), 'parser' => array( - 'options' => compact('plugin', 'path', 'file', 'name', 'connection', 'dry', 'snapshot'), + 'options' => compact('plugin', 'path', 'file', 'name', 'connection', 'dry', 'snapshot', 'yes'), 'args' => array( 'name' => array( 'help' => __d('cake_console', 'Name of schema to use.') @@ -511,7 +555,7 @@ class SchemaShell extends AppShell { ))->addSubcommand('update', array( 'help' => __d('cake_console', 'Alter the tables based on the schema file.'), 'parser' => array( - 'options' => compact('plugin', 'path', 'file', 'name', 'connection', 'dry', 'snapshot', 'force'), + 'options' => compact('plugin', 'path', 'file', 'name', 'connection', 'dry', 'snapshot', 'force', 'yes'), 'args' => array( 'name' => array( 'help' => __d('cake_console', 'Name of schema to use.') @@ -522,6 +566,7 @@ class SchemaShell extends AppShell { ) ) )); + return $parser; } diff --git a/lib/Cake/Console/Command/ServerShell.php b/lib/Cake/Console/Command/ServerShell.php new file mode 100644 index 0000000..8c7d5e5 --- /dev/null +++ b/lib/Cake/Console/Command/ServerShell.php @@ -0,0 +1,167 @@ +_host = static::DEFAULT_HOST; + $this->_port = static::DEFAULT_PORT; + $this->_documentRoot = WWW_ROOT; + } + +/** + * Starts up the Shell and displays the welcome message. + * Allows for checking and configuring prior to command or main execution + * + * Override this method if you want to remove the welcome information, + * or otherwise modify the pre-command flow. + * + * @return void + * @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell::startup + */ + public function startup() { + if (!empty($this->params['host'])) { + $this->_host = $this->params['host']; + } + if (!empty($this->params['port'])) { + $this->_port = $this->params['port']; + } + if (!empty($this->params['document_root'])) { + $this->_documentRoot = $this->params['document_root']; + } + + // for Windows + if (substr($this->_documentRoot, -1, 1) === DIRECTORY_SEPARATOR) { + $this->_documentRoot = substr($this->_documentRoot, 0, strlen($this->_documentRoot) - 1); + } + if (preg_match("/^([a-z]:)[\\\]+(.+)$/i", $this->_documentRoot, $m)) { + $this->_documentRoot = $m[1] . '\\' . $m[2]; + } + + parent::startup(); + } + +/** + * Displays a header for the shell + * + * @return void + */ + protected function _welcome() { + $this->out(); + $this->out(__d('cake_console', 'Welcome to CakePHP %s Console', 'v' . Configure::version())); + $this->hr(); + $this->out(__d('cake_console', 'App : %s', APP_DIR)); + $this->out(__d('cake_console', 'Path: %s', APP)); + $this->out(__d('cake_console', 'DocumentRoot: %s', $this->_documentRoot)); + $this->hr(); + } + +/** + * Override main() to handle action + * + * @return void + */ + public function main() { + if (version_compare(PHP_VERSION, '5.4.0') < 0) { + $this->out(__d('cake_console', 'This command is available on %s or above', 'PHP5.4')); + return; + } + + $command = sprintf("php -S %s:%d -t %s %s", + $this->_host, + $this->_port, + escapeshellarg($this->_documentRoot), + escapeshellarg($this->_documentRoot . '/index.php') + ); + + $port = ($this->_port == static::DEFAULT_PORT) ? '' : ':' . $this->_port; + $this->out(__d('cake_console', 'built-in server is running in http://%s%s/', $this->_host, $port)); + system($command); + } + +/** + * Gets the option parser instance and configures it. + * + * @return ConsoleOptionParser + */ + public function getOptionParser() { + $parser = parent::getOptionParser(); + + $parser->description(array( + __d('cake_console', 'PHP Built-in Server for CakePHP'), + __d('cake_console', '[WARN] Don\'t use this at the production environment') + ))->addOption('host', array( + 'short' => 'H', + 'help' => __d('cake_console', 'ServerHost') + ))->addOption('port', array( + 'short' => 'p', + 'help' => __d('cake_console', 'ListenPort') + ))->addOption('document_root', array( + 'short' => 'd', + 'help' => __d('cake_console', 'DocumentRoot') + )); + + return $parser; + } +} diff --git a/lib/Cake/Console/Command/Task/BakeTask.php b/lib/Cake/Console/Command/Task/BakeTask.php index e32e253..8298e11 100644 --- a/lib/Cake/Console/Command/Task/BakeTask.php +++ b/lib/Cake/Console/Command/Task/BakeTask.php @@ -2,18 +2,17 @@ /** * Base class for Bake Tasks. * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @since CakePHP(tm) v 1.3 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ App::uses('AppShell', 'Console/Command'); @@ -42,7 +41,7 @@ class BakeTask extends AppShell { /** * Flag for interactive mode * - * @var boolean + * @var bool */ public $interactive = false; @@ -59,7 +58,7 @@ class BakeTask extends AppShell { } /** - * Gets the path for output. Checks the plugin property + * Gets the path for output. Checks the plugin property * and returns the correct path. * * @return string Path to output. diff --git a/lib/Cake/Console/Command/Task/CommandTask.php b/lib/Cake/Console/Command/Task/CommandTask.php new file mode 100644 index 0000000..fca006a --- /dev/null +++ b/lib/Cake/Console/Command/Task/CommandTask.php @@ -0,0 +1,183 @@ + null, 'app' => null); + + $corePath = App::core('Console/Command'); + $shells = App::objects('file', $corePath[0]); + $shells = array_diff($shells, $skipFiles); + $this->_appendShells('CORE', $shells, $shellList); + + $appShells = App::objects('Console/Command', null, false); + $appShells = array_diff($appShells, $shells, $skipFiles); + $this->_appendShells('app', $appShells, $shellList); + + foreach ($plugins as $plugin) { + $pluginShells = App::objects($plugin . '.Console/Command'); + $this->_appendShells($plugin, $pluginShells, $shellList); + } + + return array_filter($shellList); + } + +/** + * Scan the provided paths for shells, and append them into $shellList + * + * @param string $type The type of object. + * @param array $shells The shell name. + * @param array &$shellList List of shells. + * @return void + */ + protected function _appendShells($type, $shells, &$shellList) { + foreach ($shells as $shell) { + $shellList[$type][] = Inflector::underscore(str_replace('Shell', '', $shell)); + } + } + +/** + * Return a list of all commands + * + * @return array + */ + public function commands() { + $shellList = $this->getShellList(); + + $options = array(); + foreach ($shellList as $type => $commands) { + $prefix = ''; + if (!in_array(strtolower($type), array('app', 'core'))) { + $prefix = $type . '.'; + } + + foreach ($commands as $shell) { + $options[] = $prefix . $shell; + } + } + + return $options; + } + +/** + * Return a list of subcommands for a given command + * + * @param string $commandName The command you want subcommands from. + * @return array + */ + public function subCommands($commandName) { + $Shell = $this->getShell($commandName); + + if (!$Shell) { + return array(); + } + + $taskMap = TaskCollection::normalizeObjectArray((array)$Shell->tasks); + $return = array_keys($taskMap); + $return = array_map('Inflector::underscore', $return); + + $ShellReflection = new ReflectionClass('AppShell'); + $shellMethods = $ShellReflection->getMethods(ReflectionMethod::IS_PUBLIC); + $shellMethodNames = array('main', 'help'); + foreach ($shellMethods as $method) { + $shellMethodNames[] = $method->getName(); + } + + $Reflection = new ReflectionClass($Shell); + $methods = $Reflection->getMethods(ReflectionMethod::IS_PUBLIC); + $methodNames = array(); + foreach ($methods as $method) { + $methodNames[] = $method->getName(); + } + + $return += array_diff($methodNames, $shellMethodNames); + sort($return); + + return $return; + } + +/** + * Get Shell instance for the given command + * + * @param mixed $commandName The command you want. + * @return mixed + */ + public function getShell($commandName) { + list($pluginDot, $name) = pluginSplit($commandName, true); + + if (in_array(strtolower($pluginDot), array('app.', 'core.'))) { + $commandName = $name; + $pluginDot = ''; + } + + if (!in_array($commandName, $this->commands())) { + return false; + } + + $name = Inflector::camelize($name); + $pluginDot = Inflector::camelize($pluginDot); + $class = $name . 'Shell'; + App::uses($class, $pluginDot . 'Console/Command'); + + $Shell = new $class(); + $Shell->plugin = trim($pluginDot, '.'); + $Shell->initialize(); + + return $Shell; + } + +/** + * Get Shell instance for the given command + * + * @param mixed $commandName The command to get options for. + * @return array + */ + public function options($commandName) { + $Shell = $this->getShell($commandName); + if (!$Shell) { + $parser = new ConsoleOptionParser(); + } else { + $parser = $Shell->getOptionParser(); + } + + $options = array(); + $array = $parser->options(); + foreach ($array as $name => $obj) { + $options[] = "--$name"; + $short = $obj->short(); + if ($short) { + $options[] = "-$short"; + } + } + return $options; + } + +} diff --git a/lib/Cake/Console/Command/Task/ControllerTask.php b/lib/Cake/Console/Command/Task/ControllerTask.php index 8feecc1..f9f8f70 100644 --- a/lib/Cake/Console/Command/Task/ControllerTask.php +++ b/lib/Cake/Console/Command/Task/ControllerTask.php @@ -2,18 +2,17 @@ /** * The ControllerTask handles creating and updating controller files. * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @since CakePHP(tm) v 1.2 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ App::uses('AppShell', 'Console/Command'); @@ -65,7 +64,7 @@ class ControllerTask extends BakeTask { if (!isset($this->connection)) { $this->connection = 'default'; } - if (strtolower($this->args[0]) == 'all') { + if (strtolower($this->args[0]) === 'all') { return $this->all(); } @@ -96,7 +95,7 @@ class ControllerTask extends BakeTask { } /** - * Bake All the controllers at once. Will only bake controllers for models that exist. + * Bake All the controllers at once. Will only bake controllers for models that exist. * * @return void */ @@ -105,17 +104,33 @@ class ControllerTask extends BakeTask { $this->listAll($this->connection, false); ClassRegistry::config('Model', array('ds' => $this->connection)); $unitTestExists = $this->_checkUnitTest(); + + $admin = false; + if (!empty($this->params['admin'])) { + $admin = $this->Project->getPrefix(); + } + + $controllersCreated = 0; foreach ($this->__tables as $table) { $model = $this->_modelName($table); $controller = $this->_controllerName($model); App::uses($model, 'Model'); if (class_exists($model)) { $actions = $this->bakeActions($controller); + if ($admin) { + $this->out(__d('cake_console', 'Adding %s methods', $admin)); + $actions .= "\n" . $this->bakeActions($controller, $admin); + } if ($this->bake($controller, $actions) && $unitTestExists) { $this->bakeTest($controller); } + $controllersCreated++; } } + + if (!$controllersCreated) { + $this->out(__d('cake_console', 'No Controllers were baked, Models need to exist before Controllers can be baked.')); + } } /** @@ -151,13 +166,13 @@ class ControllerTask extends BakeTask { } $doItInteractive = $this->in(implode("\n", $question), array('y', 'n'), 'y'); - if (strtolower($doItInteractive) == 'y') { + if (strtolower($doItInteractive) === 'y') { $this->interactive = true; $useDynamicScaffold = $this->in( __d('cake_console', "Would you like to use dynamic scaffolding?"), array('y', 'n'), 'n' ); - if (strtolower($useDynamicScaffold) == 'y') { + if (strtolower($useDynamicScaffold) === 'y') { $wannaBakeCrud = 'n'; $actions = 'scaffold'; } else { @@ -167,27 +182,32 @@ class ControllerTask extends BakeTask { $components = $this->doComponents(); $wannaUseSession = $this->in( - __d('cake_console', "Would you like to use Session flash messages?"), array('y','n'), 'y' + __d('cake_console', "Would you like to use the FlashComponent to display flash messages?"), array('y', 'n'), 'y' ); + + if (strtolower($wannaUseSession) === 'y') { + array_push($components, 'Session', 'Flash'); + } + array_unique($components); } } else { list($wannaBakeCrud, $wannaBakeAdminCrud) = $this->_askAboutMethods(); } - if (strtolower($wannaBakeCrud) == 'y') { - $actions = $this->bakeActions($controllerName, null, strtolower($wannaUseSession) == 'y'); + if (strtolower($wannaBakeCrud) === 'y') { + $actions = $this->bakeActions($controllerName, null, strtolower($wannaUseSession) === 'y'); } - if (strtolower($wannaBakeAdminCrud) == 'y') { + if (strtolower($wannaBakeAdminCrud) === 'y') { $admin = $this->Project->getPrefix(); - $actions .= $this->bakeActions($controllerName, $admin, strtolower($wannaUseSession) == 'y'); + $actions .= $this->bakeActions($controllerName, $admin, strtolower($wannaUseSession) === 'y'); } $baked = false; if ($this->interactive === true) { $this->confirmController($controllerName, $useDynamicScaffold, $helpers, $components); - $looksGood = $this->in(__d('cake_console', 'Look okay?'), array('y','n'), 'y'); + $looksGood = $this->in(__d('cake_console', 'Look okay?'), array('y', 'n'), 'y'); - if (strtolower($looksGood) == 'y') { + if (strtolower($looksGood) === 'y') { $baked = $this->bake($controllerName, $actions, $helpers, $components); if ($baked && $this->_checkUnitTest()) { $this->bakeTest($controllerName); @@ -205,10 +225,10 @@ class ControllerTask extends BakeTask { /** * Confirm a to be baked controller with the user * - * @param string $controllerName - * @param string $useDynamicScaffold - * @param array $helpers - * @param array $components + * @param string $controllerName The name of the controller. + * @param string $useDynamicScaffold Whether or not to use dynamic scaffolds. + * @param array $helpers The list of helpers to include. + * @param array $components The list of components to include. * @return void */ public function confirmController($controllerName, $useDynamicScaffold, $helpers, $components) { @@ -218,7 +238,7 @@ class ControllerTask extends BakeTask { $this->hr(); $this->out(__d('cake_console', "Controller Name:\n\t%s", $controllerName)); - if (strtolower($useDynamicScaffold) == 'y') { + if (strtolower($useDynamicScaffold) === 'y') { $this->out("public \$scaffold;"); } @@ -228,10 +248,10 @@ class ControllerTask extends BakeTask { ); foreach ($properties as $var => $title) { - if (count($$var)) { + if (count(${$var})) { $output = ''; - $length = count($$var); - foreach ($$var as $i => $propElement) { + $length = count(${$var}); + foreach (${$var} as $i => $propElement) { if ($i != $length - 1) { $output .= ucfirst($propElement) . ', '; } else { @@ -252,11 +272,11 @@ class ControllerTask extends BakeTask { protected function _askAboutMethods() { $wannaBakeCrud = $this->in( __d('cake_console', "Would you like to create some basic class methods \n(index(), add(), view(), edit())?"), - array('y','n'), 'n' + array('y', 'n'), 'n' ); $wannaBakeAdminCrud = $this->in( __d('cake_console', "Would you like to create the basic class methods for admin routing?"), - array('y','n'), 'n' + array('y', 'n'), 'n' ); return array($wannaBakeCrud, $wannaBakeAdminCrud); } @@ -266,7 +286,7 @@ class ControllerTask extends BakeTask { * * @param string $controllerName Controller name * @param string $admin Admin route to use - * @param boolean $wannaUseSession Set to true to use sessions, false otherwise + * @param bool $wannaUseSession Set to true to use sessions, false otherwise * @return string Baked actions */ public function bakeActions($controllerName, $admin = null, $wannaUseSession = true) { @@ -278,7 +298,7 @@ class ControllerTask extends BakeTask { App::uses($modelImport, $plugin . 'Model'); if (!class_exists($modelImport)) { $this->err(__d('cake_console', 'You must have a model for this class to build basic methods. Please try again.')); - $this->_stop(); + return $this->_stop(); } $modelObj = ClassRegistry::init($currentModelName); @@ -317,6 +337,11 @@ class ControllerTask extends BakeTask { 'plugin' => $this->plugin, 'pluginPath' => empty($this->plugin) ? '' : $this->plugin . '.' )); + + if (!in_array('Paginator', (array)$components)) { + $components[] = 'Paginator'; + } + $this->Template->set(compact('controllerName', 'actions', 'helpers', 'components', 'isScaffold')); $contents = $this->Template->generate('classes', 'controller'); @@ -349,7 +374,7 @@ class ControllerTask extends BakeTask { public function doHelpers() { return $this->_doPropertyChoices( __d('cake_console', "Would you like this controller to use other helpers\nbesides HtmlHelper and FormHelper?"), - __d('cake_console', "Please provide a comma separated list of the other\nhelper names you'd like to use.\nExample: 'Ajax, Javascript, Time'") + __d('cake_console', "Please provide a comma separated list of the other\nhelper names you'd like to use.\nExample: 'Text, Js, Time'") ); } @@ -359,10 +384,11 @@ class ControllerTask extends BakeTask { * @return array Components the user wants to use. */ public function doComponents() { - return $this->_doPropertyChoices( - __d('cake_console', "Would you like this controller to use any components?"), + $components = array('Paginator'); + return array_merge($components, $this->_doPropertyChoices( + __d('cake_console', "Would you like this controller to use other components\nbesides PaginatorComponent?"), __d('cake_console', "Please provide a comma separated list of the component names you'd like to use.\nExample: 'Acl, Security, RequestHandler'") - ); + )); } /** @@ -373,9 +399,9 @@ class ControllerTask extends BakeTask { * @return array Array of values for property. */ protected function _doPropertyChoices($prompt, $example) { - $proceed = $this->in($prompt, array('y','n'), 'n'); + $proceed = $this->in($prompt, array('y', 'n'), 'n'); $property = array(); - if (strtolower($proceed) == 'y') { + if (strtolower($proceed) === 'y') { $propertyList = $this->in($example); $propertyListTrimmed = str_replace(' ', '', $propertyList); $property = explode(',', $propertyListTrimmed); @@ -390,12 +416,12 @@ class ControllerTask extends BakeTask { * @return array Set of controllers */ public function listAll($useDbConfig = null) { - if (is_null($useDbConfig)) { + if ($useDbConfig === null) { $useDbConfig = $this->connection; } $this->__tables = $this->Model->getAllTables($useDbConfig); - if ($this->interactive == true) { + if ($this->interactive) { $this->out(__d('cake_console', 'Possible Controllers based on your current database:')); $this->hr(); $this->_controllerNames = array(); @@ -419,21 +445,21 @@ class ControllerTask extends BakeTask { $controllers = $this->listAll($useDbConfig); $enteredController = ''; - while ($enteredController == '') { + while (!$enteredController) { $enteredController = $this->in(__d('cake_console', "Enter a number from the list above,\ntype in the name of another controller, or 'q' to exit"), null, 'q'); if ($enteredController === 'q') { $this->out(__d('cake_console', 'Exit')); return $this->_stop(); } - if ($enteredController == '' || intval($enteredController) > count($controllers)) { + if (!$enteredController || (int)$enteredController > count($controllers)) { $this->err(__d('cake_console', "The Controller name you supplied was empty,\nor the number you selected was not an option. Please try again.")); $enteredController = ''; } } - if (intval($enteredController) > 0 && intval($enteredController) <= count($controllers) ) { - $controllerName = $controllers[intval($enteredController) - 1]; + if ((int)$enteredController > 0 && (int)$enteredController <= count($controllers)) { + $controllerName = $controllers[(int)$enteredController - 1]; } else { $controllerName = Inflector::camelize($enteredController); } @@ -441,31 +467,42 @@ class ControllerTask extends BakeTask { } /** - * get the option parser. + * Gets the option parser instance and configures it. * - * @return void + * @return ConsoleOptionParser */ public function getOptionParser() { $parser = parent::getOptionParser(); - return $parser->description( - __d('cake_console', 'Bake a controller for a model. Using options you can bake public, admin or both.') - )->addArgument('name', array( - 'help' => __d('cake_console', 'Name of the controller to bake. Can use Plugin.name to bake controllers into plugins.') - ))->addOption('public', array( - 'help' => __d('cake_console', 'Bake a controller with basic crud actions (index, view, add, edit, delete).'), - 'boolean' => true - ))->addOption('admin', array( - 'help' => __d('cake_console', 'Bake a controller with crud actions for one of the Routing.prefixes.'), - 'boolean' => true - ))->addOption('plugin', array( - 'short' => 'p', - 'help' => __d('cake_console', 'Plugin to bake the controller into.') - ))->addOption('connection', array( - 'short' => 'c', - 'help' => __d('cake_console', 'The connection the controller\'s model is on.') - ))->addSubcommand('all', array( - 'help' => __d('cake_console', 'Bake all controllers with CRUD methods.') - ))->epilog(__d('cake_console', 'Omitting all arguments and options will enter into an interactive mode.')); + + $parser->description( + __d('cake_console', 'Bake a controller for a model. Using options you can bake public, admin or both.' + ))->addArgument('name', array( + 'help' => __d('cake_console', 'Name of the controller to bake. Can use Plugin.name to bake controllers into plugins.') + ))->addOption('public', array( + 'help' => __d('cake_console', 'Bake a controller with basic crud actions (index, view, add, edit, delete).'), + 'boolean' => true + ))->addOption('admin', array( + 'help' => __d('cake_console', 'Bake a controller with crud actions for one of the Routing.prefixes.'), + 'boolean' => true + ))->addOption('plugin', array( + 'short' => 'p', + 'help' => __d('cake_console', 'Plugin to bake the controller into.') + ))->addOption('connection', array( + 'short' => 'c', + 'help' => __d('cake_console', 'The connection the controller\'s model is on.') + ))->addOption('theme', array( + 'short' => 't', + 'help' => __d('cake_console', 'Theme to use when baking code.') + ))->addOption('force', array( + 'short' => 'f', + 'help' => __d('cake_console', 'Force overwriting existing files without prompting.') + ))->addSubcommand('all', array( + 'help' => __d('cake_console', 'Bake all controllers with CRUD methods.') + ))->epilog( + __d('cake_console', 'Omitting all arguments and options will enter into an interactive mode.') + ); + + return $parser; } } diff --git a/lib/Cake/Console/Command/Task/DbConfigTask.php b/lib/Cake/Console/Command/Task/DbConfigTask.php index 596ad81..ee1aa6c 100644 --- a/lib/Cake/Console/Command/Task/DbConfigTask.php +++ b/lib/Cake/Console/Command/Task/DbConfigTask.php @@ -2,18 +2,17 @@ /** * The DbConfig Task handles creating and updating the database.php * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @since CakePHP(tm) v 1.2 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ App::uses('AppShell', 'Console/Command'); @@ -76,7 +75,7 @@ class DbConfigTask extends AppShell { public function execute() { if (empty($this->args)) { $this->_interactive(); - $this->_stop(); + return $this->_stop(); } } @@ -92,10 +91,10 @@ class DbConfigTask extends AppShell { $done = false; $dbConfigs = array(); - while ($done == false) { + while (!$done) { $name = ''; - while ($name == '') { + while (!$name) { $name = $this->in(__d('cake_console', "Name:"), null, 'default'); if (preg_match('/[^a-z0-9_]/i', $name)) { $name = ''; @@ -109,85 +108,85 @@ class DbConfigTask extends AppShell { $datasource = $this->in(__d('cake_console', 'Datasource:'), array('Mysql', 'Postgres', 'Sqlite', 'Sqlserver'), 'Mysql'); $persistent = $this->in(__d('cake_console', 'Persistent Connection?'), array('y', 'n'), 'n'); - if (strtolower($persistent) == 'n') { + if (strtolower($persistent) === 'n') { $persistent = 'false'; } else { $persistent = 'true'; } $host = ''; - while ($host == '') { + while (!$host) { $host = $this->in(__d('cake_console', 'Database Host:'), null, 'localhost'); } $port = ''; - while ($port == '') { + while (!$port) { $port = $this->in(__d('cake_console', 'Port?'), null, 'n'); } - if (strtolower($port) == 'n') { + if (strtolower($port) === 'n') { $port = null; } $login = ''; - while ($login == '') { + while (!$login) { $login = $this->in(__d('cake_console', 'User:'), null, 'root'); } $password = ''; $blankPassword = false; - while ($password == '' && $blankPassword == false) { + while (!$password && !$blankPassword) { $password = $this->in(__d('cake_console', 'Password:')); - if ($password == '') { + if (!$password) { $blank = $this->in(__d('cake_console', 'The password you supplied was empty. Use an empty password?'), array('y', 'n'), 'n'); - if ($blank == 'y') { + if ($blank === 'y') { $blankPassword = true; } } } $database = ''; - while ($database == '') { + while (!$database) { $database = $this->in(__d('cake_console', 'Database Name:'), null, 'cake'); } $prefix = ''; - while ($prefix == '') { + while (!$prefix) { $prefix = $this->in(__d('cake_console', 'Table Prefix?'), null, 'n'); } - if (strtolower($prefix) == 'n') { + if (strtolower($prefix) === 'n') { $prefix = null; } $encoding = ''; - while ($encoding == '') { + while (!$encoding) { $encoding = $this->in(__d('cake_console', 'Table encoding?'), null, 'n'); } - if (strtolower($encoding) == 'n') { + if (strtolower($encoding) === 'n') { $encoding = null; } $schema = ''; - if ($datasource == 'postgres') { - while ($schema == '') { + if ($datasource === 'postgres') { + while (!$schema) { $schema = $this->in(__d('cake_console', 'Table schema?'), null, 'n'); } } - if (strtolower($schema) == 'n') { + if (strtolower($schema) === 'n') { $schema = null; } $config = compact('name', 'datasource', 'persistent', 'host', 'login', 'password', 'database', 'prefix', 'encoding', 'port', 'schema'); - while ($this->_verify($config) == false) { + while (!$this->_verify($config)) { $this->_interactive(); } $dbConfigs[] = $config; $doneYet = $this->in(__d('cake_console', 'Do you wish to add another database configuration?'), null, 'n'); - if (strtolower($doneYet == 'n')) { + if (strtolower($doneYet === 'n')) { $done = true; } } @@ -200,18 +199,18 @@ class DbConfigTask extends AppShell { /** * Output verification message and bake if it looks good * - * @param array $config - * @return boolean True if user says it looks good, false otherwise + * @param array $config The config data. + * @return bool True if user says it looks good, false otherwise */ protected function _verify($config) { - $config = array_merge($this->_defaultConfig, $config); + $config += $this->_defaultConfig; extract($config); $this->out(); $this->hr(); $this->out(__d('cake_console', 'The following database configuration will be created:')); $this->hr(); $this->out(__d('cake_console', "Name: %s", $name)); - $this->out(__d('cake_console', "Datasource: %s", $datasource)); + $this->out(__d('cake_console', "Datasource: %s", $datasource)); $this->out(__d('cake_console', "Persistent: %s", $persistent)); $this->out(__d('cake_console', "Host: %s", $host)); @@ -238,7 +237,7 @@ class DbConfigTask extends AppShell { $this->hr(); $looksGood = $this->in(__d('cake_console', 'Look okay?'), array('y', 'n'), 'y'); - if (strtolower($looksGood) == 'y') { + if (strtolower($looksGood) === 'y') { return $config; } return false; @@ -248,7 +247,7 @@ class DbConfigTask extends AppShell { * Assembles and writes database.php * * @param array $configs Configuration settings to use - * @return boolean Success + * @return bool Success */ public function bake($configs) { if (!is_dir($this->path)) { @@ -265,7 +264,7 @@ class DbConfigTask extends AppShell { $temp = get_class_vars(get_class($db)); foreach ($temp as $configName => $info) { - $info = array_merge($this->_defaultConfig, $info); + $info += $this->_defaultConfig; if (!isset($info['schema'])) { $info['schema'] = null; @@ -277,11 +276,7 @@ class DbConfigTask extends AppShell { $info['port'] = null; } - if ($info['persistent'] === false) { - $info['persistent'] = 'false'; - } else { - $info['persistent'] = ($info['persistent'] == true) ? 'true' : 'false'; - } + $info['persistent'] = var_export((bool)$info['persistent'], true); $oldConfigs[] = array( 'name' => $configName, @@ -300,8 +295,8 @@ class DbConfigTask extends AppShell { } foreach ($oldConfigs as $key => $oldConfig) { - foreach ($configs as $k => $config) { - if ($oldConfig['name'] == $config['name']) { + foreach ($configs as $config) { + if ($oldConfig['name'] === $config['name']) { unset($oldConfigs[$key]); } } @@ -312,7 +307,7 @@ class DbConfigTask extends AppShell { $out .= "class DATABASE_CONFIG {\n\n"; foreach ($configs as $config) { - $config = array_merge($this->_defaultConfig, $config); + $config += $this->_defaultConfig; extract($config); if (strpos($datasource, 'Database/') === false) { @@ -373,15 +368,18 @@ class DbConfigTask extends AppShell { } /** - * get the option parser + * Gets the option parser instance and configures it. * * @return ConsoleOptionParser */ public function getOptionParser() { $parser = parent::getOptionParser(); - return $parser->description( - __d('cake_console', 'Bake new database configuration settings.') - ); + + $parser->description( + __d('cake_console', 'Bake new database configuration settings.') + ); + + return $parser; } } diff --git a/lib/Cake/Console/Command/Task/ExtractTask.php b/lib/Cake/Console/Command/Task/ExtractTask.php index 8d0777b..740528f 100644 --- a/lib/Cake/Console/Command/Task/ExtractTask.php +++ b/lib/Cake/Console/Command/Task/ExtractTask.php @@ -2,18 +2,17 @@ /** * Language string extractor * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @since CakePHP(tm) v 1.2.0.5012 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ App::uses('AppShell', 'Console/Command'); @@ -43,9 +42,9 @@ class ExtractTask extends AppShell { protected $_files = array(); /** - * Merge all domains string into the default.pot file + * Merge all domain and category strings into the default.pot file * - * @var boolean + * @var bool */ protected $_merge = false; @@ -71,7 +70,7 @@ class ExtractTask extends AppShell { protected $_tokens = array(); /** - * Extracted strings indexed by domain. + * Extracted strings indexed by category, domain, msgid and context. * * @var array */ @@ -94,21 +93,21 @@ class ExtractTask extends AppShell { /** * Holds whether this call should extract model validation messages * - * @var boolean + * @var bool */ protected $_extractValidation = true; /** * Holds the validation string domain to use for validation messages when extracting * - * @var boolean + * @var bool */ protected $_validationDomain = 'default'; /** * Holds whether this call should extract the CakePHP Lib messages * - * @var boolean + * @var bool */ protected $_extractCore = false; @@ -128,7 +127,7 @@ class ExtractTask extends AppShell { ); $response = $this->in($message, null, $defaultPath); if (strtoupper($response) === 'Q') { - $this->out(__d('cake_console', 'Extract Aborted')); + $this->err(__d('cake_console', 'Extract Aborted')); return $this->_stop(); } elseif (strtoupper($response) === 'D' && count($this->_paths)) { $this->out(); @@ -152,7 +151,7 @@ class ExtractTask extends AppShell { */ public function execute() { if (!empty($this->params['exclude'])) { - $this->_exclude = explode(',', $this->params['exclude']); + $this->_exclude = explode(',', str_replace('/', DS, $this->params['exclude'])); } if (isset($this->params['files']) && !is_array($this->params['files'])) { $this->_files = explode(',', $this->params['files']); @@ -177,14 +176,6 @@ class ExtractTask extends AppShell { $this->_extractCore = strtolower($response) === 'y'; } - if ($this->_extractCore) { - $this->_paths[] = CAKE; - $this->_exclude = array_merge($this->_exclude, array( - CAKE . 'Test', - CAKE . 'Console' . DS . 'Templates' - )); - } - if (!empty($this->params['exclude-plugins']) && $this->_isExtractingApp()) { $this->_exclude = array_merge($this->_exclude, App::path('plugins')); } @@ -196,6 +187,14 @@ class ExtractTask extends AppShell { $this->_validationDomain = $this->params['validation-domain']; } + if ($this->_extractCore) { + $this->_paths[] = CAKE; + $this->_exclude = array_merge($this->_exclude, array( + CAKE . 'Test', + CAKE . 'Console' . DS . 'Templates' + )); + } + if (isset($this->params['output'])) { $this->_output = $this->params['output']; } elseif (isset($this->params['plugin'])) { @@ -205,9 +204,9 @@ class ExtractTask extends AppShell { while (true) { $response = $this->in($message, null, rtrim($this->_paths[0], DS) . DS . 'Locale'); if (strtoupper($response) === 'Q') { - $this->out(__d('cake_console', 'Extract Aborted')); - $this->_stop(); - } elseif (is_dir($response)) { + $this->err(__d('cake_console', 'Extract Aborted')); + return $this->_stop(); + } elseif ($this->_isPathUsable($response)) { $this->_output = $response . DS; break; } else { @@ -221,14 +220,20 @@ class ExtractTask extends AppShell { $this->_merge = !(strtolower($this->params['merge']) === 'no'); } else { $this->out(); - $response = $this->in(__d('cake_console', 'Would you like to merge all domains strings into the default.pot file?'), array('y', 'n'), 'n'); + $response = $this->in(__d('cake_console', 'Would you like to merge all domain and category strings into the default.pot file?'), array('y', 'n'), 'n'); $this->_merge = strtolower($response) === 'y'; } if (empty($this->_files)) { $this->_searchFiles(); } + $this->_output = rtrim($this->_output, DS) . DS; + if (!$this->_isPathUsable($this->_output)) { + $this->err(__d('cake_console', 'The output directory %s was not found or writable.', $this->_output)); + return $this->_stop(); + } + $this->_extract(); } @@ -237,27 +242,33 @@ class ExtractTask extends AppShell { * * Takes care of duplicate translations * - * @param string $domain - * @param string $msgid - * @param array $details + * @param string $category The category + * @param string $domain The domain + * @param string $msgid The message string + * @param array $details The file and line references + * @return void */ - protected function _addTranslation($domain, $msgid, $details = array()) { - if (empty($this->_translations[$domain][$msgid])) { - $this->_translations[$domain][$msgid] = array( - 'msgid_plural' => false - ); + protected function _addTranslation($category, $domain, $msgid, $details = array()) { + $context = ''; + if (isset($details['msgctxt'])) { + $context = $details['msgctxt']; + } + + if (empty($this->_translations[$category][$domain][$msgid][$context])) { + $this->_translations[$category][$domain][$msgid][$context] = array( + 'msgid_plural' => false, + ); } if (isset($details['msgid_plural'])) { - $this->_translations[$domain][$msgid]['msgid_plural'] = $details['msgid_plural']; + $this->_translations[$category][$domain][$msgid][$context]['msgid_plural'] = $details['msgid_plural']; } - if (isset($details['file'])) { $line = 0; if (isset($details['line'])) { $line = $details['line']; } - $this->_translations[$domain][$msgid]['references'][$details['file']][] = $line; + $this->_translations[$category][$domain][$msgid][$context]['references'][$details['file']][] = $line; } } @@ -289,52 +300,59 @@ class ExtractTask extends AppShell { } /** - * Get & configure the option parser + * Gets the option parser instance and configures it. * - * @return void + * @return ConsoleOptionParser */ public function getOptionParser() { $parser = parent::getOptionParser(); - return $parser->description(__d('cake_console', 'CakePHP Language String Extraction:')) - ->addOption('app', array('help' => __d('cake_console', 'Directory where your application is located.'))) - ->addOption('paths', array('help' => __d('cake_console', 'Comma separated list of paths.'))) - ->addOption('merge', array( - 'help' => __d('cake_console', 'Merge all domain strings into the default.po file.'), - 'choices' => array('yes', 'no') - )) - ->addOption('output', array('help' => __d('cake_console', 'Full path to output directory.'))) - ->addOption('files', array('help' => __d('cake_console', 'Comma separated list of files.'))) - ->addOption('exclude-plugins', array( - 'boolean' => true, - 'default' => true, - 'help' => __d('cake_console', 'Ignores all files in plugins if this command is run inside from the same app directory.') - )) - ->addOption('plugin', array( - 'help' => __d('cake_console', 'Extracts tokens only from the plugin specified and puts the result in the plugin\'s Locale directory.') - )) - ->addOption('ignore-model-validation', array( - 'boolean' => true, - 'default' => false, - 'help' => __d('cake_console', 'Ignores validation messages in the $validate property.' . - ' If this flag is not set and the command is run from the same app directory,' . - ' all messages in model validation rules will be extracted as tokens.') - )) - ->addOption('validation-domain', array( - 'help' => __d('cake_console', 'If set to a value, the localization domain to be used for model validation messages.') - )) - ->addOption('exclude', array( - 'help' => __d('cake_console', 'Comma separated list of directories to exclude.' . - ' Any path containing a path segment with the provided values will be skipped. E.g. test,vendors') - )) - ->addOption('overwrite', array( - 'boolean' => true, - 'default' => false, - 'help' => __d('cake_console', 'Always overwrite existing .pot files.') - )) - ->addOption('extract-core', array( - 'help' => __d('cake_console', 'Extract messages from the CakePHP core libs.'), - 'choices' => array('yes', 'no') - )); + + $parser->description( + __d('cake_console', 'CakePHP Language String Extraction:') + )->addOption('app', array( + 'help' => __d('cake_console', 'Directory where your application is located.') + ))->addOption('paths', array( + 'help' => __d('cake_console', 'Comma separated list of paths.') + ))->addOption('merge', array( + 'help' => __d('cake_console', 'Merge all domain and category strings into the default.po file.'), + 'choices' => array('yes', 'no') + ))->addOption('no-location', array( + 'boolean' => true, + 'default' => false, + 'help' => __d('cake_console', 'Do not write lines with locations'), + ))->addOption('output', array( + 'help' => __d('cake_console', 'Full path to output directory.') + ))->addOption('files', array( + 'help' => __d('cake_console', 'Comma separated list of files.') + ))->addOption('exclude-plugins', array( + 'boolean' => true, + 'default' => true, + 'help' => __d('cake_console', 'Ignores all files in plugins if this command is run inside from the same app directory.') + ))->addOption('plugin', array( + 'help' => __d('cake_console', 'Extracts tokens only from the plugin specified and puts the result in the plugin\'s Locale directory.') + ))->addOption('ignore-model-validation', array( + 'boolean' => true, + 'default' => false, + 'help' => __d('cake_console', 'Ignores validation messages in the $validate property.' . + ' If this flag is not set and the command is run from the same app directory,' . + ' all messages in model validation rules will be extracted as tokens.' + ) + ))->addOption('validation-domain', array( + 'help' => __d('cake_console', 'If set to a value, the localization domain to be used for model validation messages.') + ))->addOption('exclude', array( + 'help' => __d('cake_console', 'Comma separated list of directories to exclude.' . + ' Any path containing a path segment with the provided values will be skipped. E.g. test,vendors' + ) + ))->addOption('overwrite', array( + 'boolean' => true, + 'default' => false, + 'help' => __d('cake_console', 'Always overwrite existing .pot files.') + ))->addOption('extract-core', array( + 'help' => __d('cake_console', 'Extract messages from the CakePHP core libs.'), + 'choices' => array('yes', 'no') + )); + + return $parser; } /** @@ -345,14 +363,14 @@ class ExtractTask extends AppShell { protected function _extractTokens() { foreach ($this->_files as $file) { $this->_file = $file; - $this->out(__d('cake_console', 'Processing %s...', $file)); + $this->out(__d('cake_console', 'Processing %s...', $file), 1, Shell::VERBOSE); $code = file_get_contents($file); $allTokens = token_get_all($code); $this->_tokens = array(); foreach ($allTokens as $token) { - if (!is_array($token) || ($token[0] != T_WHITESPACE && $token[0] != T_INLINE_HTML)) { + if (!is_array($token) || ($token[0] !== T_WHITESPACE && $token[0] !== T_INLINE_HTML)) { $this->_tokens[] = $token; } } @@ -360,10 +378,19 @@ class ExtractTask extends AppShell { $this->_parse('__', array('singular')); $this->_parse('__n', array('singular', 'plural')); $this->_parse('__d', array('domain', 'singular')); - $this->_parse('__c', array('singular')); - $this->_parse('__dc', array('domain', 'singular')); + $this->_parse('__c', array('singular', 'category')); + $this->_parse('__dc', array('domain', 'singular', 'category')); $this->_parse('__dn', array('domain', 'singular', 'plural')); - $this->_parse('__dcn', array('domain', 'singular', 'plural')); + $this->_parse('__dcn', array('domain', 'singular', 'plural', 'count', 'category')); + + $this->_parse('__x', array('context', 'singular')); + $this->_parse('__xn', array('context', 'singular', 'plural')); + $this->_parse('__dx', array('domain', 'context', 'singular')); + $this->_parse('__dxc', array('domain', 'context', 'singular', 'category')); + $this->_parse('__dxn', array('domain', 'context', 'singular', 'plural')); + $this->_parse('__dxcn', array('domain', 'context', 'singular', 'plural', 'count', 'category')); + $this->_parse('__xc', array('context', 'singular', 'category')); + } } @@ -371,11 +398,12 @@ class ExtractTask extends AppShell { * Parse tokens * * @param string $functionName Function name that indicates translatable string (e.g: '__') - * @param array $map Array containing what variables it will find (e.g: domain, singular, plural) + * @param array $map Array containing what variables it will find (e.g: category, domain, singular, plural) * @return void */ protected function _parse($functionName, $map) { $count = 0; + $categories = array('LC_ALL', 'LC_COLLATE', 'LC_CTYPE', 'LC_MONETARY', 'LC_NUMERIC', 'LC_TIME', 'LC_MESSAGES'); $tokenCount = count($this->_tokens); while (($tokenCount - $count) > 1) { @@ -387,14 +415,14 @@ class ExtractTask extends AppShell { } list($type, $string, $line) = $countToken; - if (($type == T_STRING) && ($string == $functionName) && ($firstParenthesis == '(')) { + if (($type == T_STRING) && ($string === $functionName) && ($firstParenthesis === '(')) { $position = $count; $depth = 0; - while ($depth == 0) { - if ($this->_tokens[$position] == '(') { + while (!$depth) { + if ($this->_tokens[$position] === '(') { $depth++; - } elseif ($this->_tokens[$position] == ')') { + } elseif ($this->_tokens[$position] === ')') { $depth--; } $position++; @@ -403,8 +431,12 @@ class ExtractTask extends AppShell { $mapCount = count($map); $strings = $this->_getStrings($position, $mapCount); - if ($mapCount == count($strings)) { + if ($mapCount === count($strings)) { extract(array_combine($map, $strings)); + $category = isset($category) ? $category : 6; + $category = (int)$category; + $categoryName = $categories[$category]; + $domain = isset($domain) ? $domain : 'default'; $details = array( 'file' => $this->_file, @@ -413,8 +445,14 @@ class ExtractTask extends AppShell { if (isset($plural)) { $details['msgid_plural'] = $plural; } - $this->_addTranslation($domain, $singular, $details); - } else { + if (isset($context)) { + $details['msgctxt'] = $context; + } + // Skip LC_TIME files as we use a special file format for them. + if ($categoryName !== 'LC_TIME') { + $this->_addTranslation($categoryName, $domain, $singular, $details); + } + } elseif (!is_array($this->_tokens[$count - 1]) || $this->_tokens[$count - 1][0] != T_FUNCTION) { $this->_markerError($this->_file, $line, $functionName, $count); } } @@ -433,11 +471,29 @@ class ExtractTask extends AppShell { return; } + $plugins = array(null); + if (empty($this->params['exclude-plugins'])) { + $plugins = array_merge($plugins, App::objects('plugin', null, false)); + } + foreach ($plugins as $plugin) { + $this->_extractPluginValidationMessages($plugin); + } + } + +/** + * Extract validation messages from application or plugin models + * + * @param string $plugin Plugin name or `null` to process application models + * @return void + */ + protected function _extractPluginValidationMessages($plugin = null) { App::uses('AppModel', 'Model'); - $plugin = null; - if (!empty($this->params['plugin'])) { - App::uses($this->params['plugin'] . 'AppModel', $this->params['plugin'] . '.Model'); - $plugin = $this->params['plugin'] . '.'; + if (!empty($plugin)) { + if (!CakePlugin::loaded($plugin)) { + return; + } + App::uses($plugin . 'AppModel', $plugin . '.Model'); + $plugin = $plugin . '.'; } $models = App::objects($plugin . 'Model', null, false); @@ -472,15 +528,16 @@ class ExtractTask extends AppShell { * @param array $rules the set of validation rules for the field * @param string $file the file name where this validation rule was found * @param string $domain default domain to bind the validations to + * @param string $category the translation category * @return void */ - protected function _processValidationRules($field, $rules, $file, $domain) { + protected function _processValidationRules($field, $rules, $file, $domain, $category = 'LC_MESSAGES') { if (!is_array($rules)) { return; } $dims = Hash::dimensions($rules); - if ($dims == 1 || ($dims == 2 && isset($rules['message']))) { + if ($dims === 1 || ($dims === 2 && isset($rules['message']))) { $rules = array($rules); } @@ -496,11 +553,12 @@ class ExtractTask extends AppShell { $msgid = $rule; } if ($msgid) { + $msgid = $this->_formatString(sprintf("'%s'", $msgid)); $details = array( 'file' => $file, 'line' => 'validation for field ' . $field ); - $this->_addTranslation($domain, $msgid, $details); + $this->_addTranslation($category, $domain, $msgid, $details); } } } @@ -513,31 +571,47 @@ class ExtractTask extends AppShell { protected function _buildFiles() { $paths = $this->_paths; $paths[] = realpath(APP) . DS; - foreach ($this->_translations as $domain => $translations) { - foreach ($translations as $msgid => $details) { - $plural = $details['msgid_plural']; - $files = $details['references']; - $occurrences = array(); - foreach ($files as $file => $lines) { - $lines = array_unique($lines); - $occurrences[] = $file . ':' . implode(';', $lines); - } - $occurrences = implode("\n#: ", $occurrences); - $header = '#: ' . str_replace($paths, '', $occurrences) . "\n"; - if ($plural === false) { - $sentence = "msgid \"{$msgid}\"\n"; - $sentence .= "msgstr \"\"\n\n"; - } else { - $sentence = "msgid \"{$msgid}\"\n"; - $sentence .= "msgid_plural \"{$plural}\"\n"; - $sentence .= "msgstr[0] \"\"\n"; - $sentence .= "msgstr[1] \"\"\n\n"; - } + usort($paths, function ($a, $b) { + return strlen($b) - strlen($a); + }); - $this->_store($domain, $header, $sentence); - if ($domain != 'default' && $this->_merge) { - $this->_store('default', $header, $sentence); + foreach ($this->_translations as $category => $domains) { + foreach ($domains as $domain => $translations) { + foreach ($translations as $msgid => $contexts) { + foreach ($contexts as $context => $details) { + $plural = $details['msgid_plural']; + $header = ''; + if (empty($this->params['no-location'])) { + $files = $details['references']; + $occurrences = array(); + foreach ($files as $file => $lines) { + $lines = array_unique($lines); + $occurrences[] = $file . ':' . implode(';', $lines); + } + $occurrences = implode("\n#: ", $occurrences); + $header = '#: ' . str_replace(DS, '/', str_replace($paths, '', $occurrences)) . "\n"; + } + + $sentence = ''; + if ($context) { + $sentence .= "msgctxt \"{$context}\"\n"; + } + if ($plural === false) { + $sentence .= "msgid \"{$msgid}\"\n"; + $sentence .= "msgstr \"\"\n\n"; + } else { + $sentence .= "msgid \"{$msgid}\"\n"; + $sentence .= "msgid_plural \"{$plural}\"\n"; + $sentence .= "msgstr[0] \"\"\n"; + $sentence .= "msgstr[1] \"\"\n\n"; + } + + $this->_store($category, $domain, $header, $sentence); + if (($category !== 'LC_MESSAGES' || $domain !== 'default') && $this->_merge) { + $this->_store('LC_MESSAGES', 'default', $header, $sentence); + } + } } } } @@ -546,19 +620,23 @@ class ExtractTask extends AppShell { /** * Prepare a file to be stored * - * @param string $domain - * @param string $header - * @param string $sentence + * @param string $category The category + * @param string $domain The domain + * @param string $header The header content. + * @param string $sentence The sentence to store. * @return void */ - protected function _store($domain, $header, $sentence) { - if (!isset($this->_storage[$domain])) { - $this->_storage[$domain] = array(); + protected function _store($category, $domain, $header, $sentence) { + if (!isset($this->_storage[$category])) { + $this->_storage[$category] = array(); } - if (!isset($this->_storage[$domain][$sentence])) { - $this->_storage[$domain][$sentence] = $header; + if (!isset($this->_storage[$category][$domain])) { + $this->_storage[$category][$domain] = array(); + } + if (!isset($this->_storage[$category][$domain][$sentence])) { + $this->_storage[$category][$domain][$sentence] = $header; } else { - $this->_storage[$domain][$sentence] .= $header; + $this->_storage[$category][$domain][$sentence] .= $header; } } @@ -572,36 +650,42 @@ class ExtractTask extends AppShell { if (!empty($this->params['overwrite'])) { $overwriteAll = true; } - - foreach ($this->_storage as $domain => $sentences) { - $output = $this->_writeHeader(); - foreach ($sentences as $sentence => $header) { - $output .= $header . $sentence; - } - - $filename = $domain . '.pot'; - $File = new File($this->_output . $filename); - $response = ''; - while ($overwriteAll === false && $File->exists() && strtoupper($response) !== 'Y') { - $this->out(); - $response = $this->in( - __d('cake_console', 'Error: %s already exists in this location. Overwrite? [Y]es, [N]o, [A]ll', $filename), - array('y', 'n', 'a'), - 'y' - ); - if (strtoupper($response) === 'N') { - $response = ''; - while ($response == '') { - $response = $this->in(__d('cake_console', "What would you like to name this file?"), null, 'new_' . $filename); - $File = new File($this->_output . $response); - $filename = $response; - } - } elseif (strtoupper($response) === 'A') { - $overwriteAll = true; + foreach ($this->_storage as $category => $domains) { + foreach ($domains as $domain => $sentences) { + $output = $this->_writeHeader(); + foreach ($sentences as $sentence => $header) { + $output .= $header . $sentence; } + + $filename = $domain . '.pot'; + if ($category === 'LC_MESSAGES') { + $File = new File($this->_output . $filename); + } else { + new Folder($this->_output . $category, true); + $File = new File($this->_output . $category . DS . $filename); + } + $response = ''; + while ($overwriteAll === false && $File->exists() && strtoupper($response) !== 'Y') { + $this->out(); + $response = $this->in( + __d('cake_console', 'Error: %s already exists in this location. Overwrite? [Y]es, [N]o, [A]ll', $filename), + array('y', 'n', 'a'), + 'y' + ); + if (strtoupper($response) === 'N') { + $response = ''; + while (!$response) { + $response = $this->in(__d('cake_console', "What would you like to name this file?"), null, 'new_' . $filename); + $File = new File($this->_output . $response); + $filename = $response; + } + } elseif (strtoupper($response) === 'A') { + $overwriteAll = true; + } + } + $File->write($output); + $File->close(); } - $File->write($output); - $File->close(); } } @@ -611,14 +695,13 @@ class ExtractTask extends AppShell { * @return string Translation template header */ protected function _writeHeader() { - $output = "# LANGUAGE translation of CakePHP Application\n"; + $output = "# LANGUAGE translation of CakePHP Application\n"; $output .= "# Copyright YEAR NAME \n"; $output .= "#\n"; $output .= "#, fuzzy\n"; $output .= "msgid \"\"\n"; $output .= "msgstr \"\"\n"; $output .= "\"Project-Id-Version: PROJECT VERSION\\n\"\n"; - $output .= "\"POT-Creation-Date: " . date("Y-m-d H:iO") . "\\n\"\n"; $output .= "\"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\\n\"\n"; $output .= "\"Last-Translator: NAME \\n\"\n"; $output .= "\"Language-Team: LANGUAGE \\n\"\n"; @@ -632,18 +715,18 @@ class ExtractTask extends AppShell { /** * Get the strings from the position forward * - * @param integer $position Actual position on tokens array - * @param integer $target Number of strings to extract + * @param int &$position Actual position on tokens array + * @param int $target Number of strings to extract * @return array Strings extracted */ protected function _getStrings(&$position, $target) { $strings = array(); $count = count($strings); - while ($count < $target && ($this->_tokens[$position] == ',' || $this->_tokens[$position][0] == T_CONSTANT_ENCAPSED_STRING)) { + while ($count < $target && ($this->_tokens[$position] === ',' || $this->_tokens[$position][0] == T_CONSTANT_ENCAPSED_STRING || $this->_tokens[$position][0] == T_LNUMBER)) { $count = count($strings); - if ($this->_tokens[$position][0] == T_CONSTANT_ENCAPSED_STRING && $this->_tokens[$position + 1] == '.') { + if ($this->_tokens[$position][0] == T_CONSTANT_ENCAPSED_STRING && $this->_tokens[$position + 1] === '.') { $string = ''; - while ($this->_tokens[$position][0] == T_CONSTANT_ENCAPSED_STRING || $this->_tokens[$position] == '.') { + while ($this->_tokens[$position][0] == T_CONSTANT_ENCAPSED_STRING || $this->_tokens[$position] === '.') { if ($this->_tokens[$position][0] == T_CONSTANT_ENCAPSED_STRING) { $string .= $this->_formatString($this->_tokens[$position][1]); } @@ -652,6 +735,8 @@ class ExtractTask extends AppShell { $strings[] = $string; } elseif ($this->_tokens[$position][0] == T_CONSTANT_ENCAPSED_STRING) { $strings[] = $this->_formatString($this->_tokens[$position][1]); + } elseif ($this->_tokens[$position][0] == T_LNUMBER) { + $strings[] = $this->_tokens[$position][1]; } $position++; } @@ -667,7 +752,7 @@ class ExtractTask extends AppShell { protected function _formatString($string) { $quote = substr($string, 0, 1); $string = substr($string, 1, -1); - if ($quote == '"') { + if ($quote === '"') { $string = stripcslashes($string); } else { $string = strtr($string, array("\\'" => "'", "\\\\" => "\\")); @@ -680,33 +765,33 @@ class ExtractTask extends AppShell { * Indicate an invalid marker on a processed file * * @param string $file File where invalid marker resides - * @param integer $line Line number + * @param int $line Line number * @param string $marker Marker found - * @param integer $count Count + * @param int $count Count * @return void */ protected function _markerError($file, $line, $marker, $count) { - $this->out(__d('cake_console', "Invalid marker content in %s:%s\n* %s(", $file, $line, $marker), true); + $this->err(__d('cake_console', "Invalid marker content in %s:%s\n* %s(", $file, $line, $marker)); $count += 2; $tokenCount = count($this->_tokens); $parenthesis = 1; while ((($tokenCount - $count) > 0) && $parenthesis) { if (is_array($this->_tokens[$count])) { - $this->out($this->_tokens[$count][1], false); + $this->err($this->_tokens[$count][1], false); } else { - $this->out($this->_tokens[$count], false); - if ($this->_tokens[$count] == '(') { + $this->err($this->_tokens[$count], false); + if ($this->_tokens[$count] === '(') { $parenthesis++; } - if ($this->_tokens[$count] == ')') { + if ($this->_tokens[$count] === ')') { $parenthesis--; } } $count++; } - $this->out("\n", true); + $this->err("\n", true); } /** @@ -726,29 +811,36 @@ class ExtractTask extends AppShell { } $pattern = '/' . implode('|', $exclude) . '/'; } - foreach ($this->_paths as $path) { - $Folder = new Folder($path); + foreach ($this->_paths as $i => $path) { + $this->_paths[$i] = realpath($path) . DS; + $Folder = new Folder($this->_paths[$i]); $files = $Folder->findRecursive('.*\.(php|ctp|thtml|inc|tpl)', true); if (!empty($pattern)) { - foreach ($files as $i => $file) { - if (preg_match($pattern, $file)) { - unset($files[$i]); - } - } + $files = preg_grep($pattern, $files, PREG_GREP_INVERT); $files = array_values($files); } $this->_files = array_merge($this->_files, $files); } + $this->_files = array_unique($this->_files); } /** * Returns whether this execution is meant to extract string only from directories in folder represented by the * APP constant, i.e. this task is extracting strings from same application. * - * @return boolean + * @return bool */ protected function _isExtractingApp() { return $this->_paths === array(APP); } +/** + * Checks whether or not a given path is usable for writing. + * + * @param string $path Path to folder + * @return bool true if it exists and is writable, false otherwise + */ + protected function _isPathUsable($path) { + return is_dir($path) && is_writable($path); + } } diff --git a/lib/Cake/Console/Command/Task/FixtureTask.php b/lib/Cake/Console/Command/Task/FixtureTask.php index 92e5154..d0329e9 100644 --- a/lib/Cake/Console/Command/Task/FixtureTask.php +++ b/lib/Cake/Console/Command/Task/FixtureTask.php @@ -2,18 +2,17 @@ /** * The FixtureTask handles creating and updating fixture files. * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @since CakePHP(tm) v 1.3 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ App::uses('AppShell', 'Console/Command'); @@ -61,32 +60,48 @@ class FixtureTask extends BakeTask { } /** - * get the option parser. + * Gets the option parser instance and configures it. * - * @return void + * @return ConsoleOptionParser */ public function getOptionParser() { $parser = parent::getOptionParser(); - return $parser->description( + + $parser->description( __d('cake_console', 'Generate fixtures for use with the test suite. You can use `bake fixture all` to bake all fixtures.') )->addArgument('name', array( 'help' => __d('cake_console', 'Name of the fixture to bake. Can use Plugin.name to bake plugin fixtures.') ))->addOption('count', array( 'help' => __d('cake_console', 'When using generated data, the number of records to include in the fixture(s).'), 'short' => 'n', - 'default' => 10 + 'default' => 1 ))->addOption('connection', array( 'help' => __d('cake_console', 'Which database configuration to use for baking.'), 'short' => 'c', 'default' => 'default' ))->addOption('plugin', array( 'help' => __d('cake_console', 'CamelCased name of the plugin to bake fixtures for.'), - 'short' => 'p', + 'short' => 'p' + ))->addOption('schema', array( + 'help' => __d('cake_console', 'Importing schema for fixtures rather than hardcoding it.'), + 'short' => 's', + 'boolean' => true + ))->addOption('theme', array( + 'short' => 't', + 'help' => __d('cake_console', 'Theme to use when baking code.') + ))->addOption('force', array( + 'short' => 'f', + 'help' => __d('cake_console', 'Force overwriting existing files without prompting.') ))->addOption('records', array( - 'help' => __d('cake_console', 'Used with --count and /all commands to pull [n] records from the live tables, where [n] is either --count or the default of 10'), + 'help' => __d('cake_console', 'Used with --count and /all commands to pull [n] records from the live tables, ' . + 'where [n] is either --count or the default of 10.'), 'short' => 'r', 'boolean' => true - ))->epilog(__d('cake_console', 'Omitting all arguments and options will enter into an interactive mode.')); + ))->epilog( + __d('cake_console', 'Omitting all arguments and options will enter into an interactive mode.') + ); + + return $parser; } /** @@ -106,16 +121,17 @@ class FixtureTask extends BakeTask { if (!isset($this->connection)) { $this->connection = 'default'; } - if (strtolower($this->args[0]) == 'all') { + if (strtolower($this->args[0]) === 'all') { return $this->all(); } $model = $this->_modelName($this->args[0]); - $this->bake($model); + $importOptions = $this->importOptions($model); + $this->bake($model, false, $importOptions); } } /** - * Bake All the Fixtures at once. Will only bake fixtures for models that exist. + * Bake All the Fixtures at once. Will only bake fixtures for models that exist. * * @return void */ @@ -123,9 +139,14 @@ class FixtureTask extends BakeTask { $this->interactive = false; $this->Model->interactive = false; $tables = $this->Model->listAll($this->connection, false); + foreach ($tables as $table) { $model = $this->_modelName($table); - $this->bake($model); + $importOptions = array(); + if (!empty($this->params['schema'])) { + $importOptions['schema'] = $model; + } + $this->bake($model, false, $importOptions); } } @@ -157,18 +178,32 @@ class FixtureTask extends BakeTask { */ public function importOptions($modelName) { $options = array(); - $doSchema = $this->in(__d('cake_console', 'Would you like to import schema for this fixture?'), array('y', 'n'), 'n'); - if ($doSchema == 'y') { - $options['schema'] = $modelName; + $plugin = ''; + if (isset($this->params['plugin'])) { + $plugin = $this->params['plugin'] . '.'; } - $doRecords = $this->in(__d('cake_console', 'Would you like to use record importing for this fixture?'), array('y', 'n'), 'n'); - if ($doRecords == 'y') { - $options['records'] = true; + + if (!empty($this->params['schema'])) { + $options['schema'] = $plugin . $modelName; + } elseif ($this->interactive) { + $doSchema = $this->in(__d('cake_console', 'Would you like to import schema for this fixture?'), array('y', 'n'), 'n'); + if ($doSchema === 'y') { + $options['schema'] = $modelName; + } } - if ($doRecords == 'n') { + + if (!empty($this->params['records'])) { + $options['fromTable'] = true; + } elseif ($this->interactive) { + $doRecords = $this->in(__d('cake_console', 'Would you like to use record importing for this fixture?'), array('y', 'n'), 'n'); + if ($doRecords === 'y') { + $options['records'] = true; + } + } + if (!isset($options['records']) && $this->interactive) { $prompt = __d('cake_console', "Would you like to build this fixture with data from %s's table?", $modelName); $fromTable = $this->in($prompt, array('y', 'n'), 'n'); - if (strtolower($fromTable) == 'y') { + if (strtolower($fromTable) === 'y') { $options['fromTable'] = true; } } @@ -181,7 +216,7 @@ class FixtureTask extends BakeTask { * @param string $model Name of model to bake. * @param string $useTable Name of table to use. * @param array $importOptions Options for public $import - * @return string Baked fixture content + * @return string|null Baked fixture content, otherwise null. */ public function bake($model, $useTable = false, $importOptions = array()) { App::uses('CakeSchema', 'Model'); @@ -202,7 +237,7 @@ class FixtureTask extends BakeTask { if (isset($importOptions['records'])) { $importBits[] = "'records' => true"; } - if ($this->connection != 'default') { + if ($this->connection !== 'default') { $importBits[] .= "'connection' => '{$this->connection}'"; } if (!empty($importBits)) { @@ -213,12 +248,12 @@ class FixtureTask extends BakeTask { $this->_Schema = new CakeSchema(); $data = $this->_Schema->read(array('models' => false, 'connection' => $this->connection)); if (!isset($data['tables'][$useTable])) { - $this->err('Could not find your selected table ' . $useTable); - return false; + $this->err("Warning: Could not find the '${useTable}' table for ${model}."); + return null; } $tableInfo = $data['tables'][$useTable]; - if (is_null($modelImport)) { + if ($modelImport === null) { $schema = $this->_generateSchema($tableInfo); } @@ -232,7 +267,7 @@ class FixtureTask extends BakeTask { if (!empty($this->params['records']) || isset($importOptions['fromTable'])) { $records = $this->_makeRecordString($this->_getRecordsFromTable($model, $useTable)); } - $out = $this->generateFixtureFile($model, compact('records', 'table', 'schema', 'import', 'fields')); + $out = $this->generateFixtureFile($model, compact('records', 'table', 'schema', 'import')); return $out; } @@ -279,15 +314,15 @@ class FixtureTask extends BakeTask { * @return string fields definitions */ protected function _generateSchema($tableInfo) { - $schema = $this->_Schema->generateTable('f', $tableInfo); - return substr($schema, 13, -2); + $schema = trim($this->_Schema->generateTable('f', $tableInfo), "\n"); + return substr($schema, 13, -1); } /** * Generate String representation of Records * * @param array $tableInfo Table schema array - * @param integer $recordCount + * @param int $recordCount The number of records to generate. * @return array Array of records to use in the fixture. */ protected function _generateRecords($tableInfo, $recordCount = 1) { @@ -298,41 +333,42 @@ class FixtureTask extends BakeTask { if (empty($fieldInfo['type'])) { continue; } + $insert = ''; switch ($fieldInfo['type']) { case 'integer': case 'float': $insert = $i + 1; - break; + break; case 'string': case 'binary': $isPrimaryUuid = ( - isset($fieldInfo['key']) && strtolower($fieldInfo['key']) == 'primary' && + isset($fieldInfo['key']) && strtolower($fieldInfo['key']) === 'primary' && isset($fieldInfo['length']) && $fieldInfo['length'] == 36 ); if ($isPrimaryUuid) { - $insert = String::uuid(); + $insert = CakeText::uuid(); } else { $insert = "Lorem ipsum dolor sit amet"; if (!empty($fieldInfo['length'])) { - $insert = substr($insert, 0, (int)$fieldInfo['length'] - 2); + $insert = substr($insert, 0, (int)$fieldInfo['length'] - 2); } } - break; + break; case 'timestamp': $insert = time(); - break; + break; case 'datetime': $insert = date('Y-m-d H:i:s'); - break; + break; case 'date': $insert = date('Y-m-d'); - break; + break; case 'time': $insert = date('H:i:s'); - break; + break; case 'boolean': $insert = 1; - break; + break; case 'text': $insert = "Lorem ipsum dolor sit amet, aliquet feugiat."; $insert .= " Convallis morbi fringilla gravida,"; @@ -341,7 +377,7 @@ class FixtureTask extends BakeTask { $insert .= " vestibulum massa neque ut et, id hendrerit sit,"; $insert .= " feugiat in taciti enim proin nibh, tempor dignissim, rhoncus"; $insert .= " duis vestibulum nunc mattis convallis."; - break; + break; } $record[$field] = $insert; } @@ -351,7 +387,7 @@ class FixtureTask extends BakeTask { } /** - * Convert a $records array into a a string. + * Convert a $records array into a string. * * @param array $records Array of records to be converted to string * @return string A string value of the $records array. @@ -384,25 +420,32 @@ class FixtureTask extends BakeTask { * @return array Array of records. */ protected function _getRecordsFromTable($modelName, $useTable = null) { + $modelObject = new Model(array('name' => $modelName, 'table' => $useTable, 'ds' => $this->connection)); if ($this->interactive) { $condition = null; $prompt = __d('cake_console', "Please provide a SQL fragment to use as conditions\nExample: WHERE 1=1"); while (!$condition) { $condition = $this->in($prompt, null, 'WHERE 1=1'); } + + $recordsFound = $modelObject->find('count', array( + 'conditions' => $condition, + 'recursive' => -1, + )); + $prompt = __d('cake_console', "How many records do you want to import?"); - $recordCount = $this->in($prompt, null, 10); + $recordCount = $this->in($prompt, null, ($recordsFound < 10 ) ? $recordsFound : 10); } else { $condition = 'WHERE 1=1'; $recordCount = (isset($this->params['count']) ? $this->params['count'] : 10); } - $modelObject = new Model(array('name' => $modelName, 'table' => $useTable, 'ds' => $this->connection)); + $records = $modelObject->find('all', array( 'conditions' => $condition, 'recursive' => -1, 'limit' => $recordCount )); - $db = $modelObject->getDatasource(); + $schema = $modelObject->schema(true); $out = array(); foreach ($records as $record) { diff --git a/lib/Cake/Console/Command/Task/ModelTask.php b/lib/Cake/Console/Command/Task/ModelTask.php index df2725d..2dc03a5 100644 --- a/lib/Cake/Console/Command/Task/ModelTask.php +++ b/lib/Cake/Console/Command/Task/ModelTask.php @@ -2,18 +2,17 @@ /** * The ModelTask handles creating and updating models files. * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @since CakePHP(tm) v 1.2 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ App::uses('AppShell', 'Console/Command'); @@ -97,7 +96,7 @@ class ModelTask extends BakeTask { if (!isset($this->connection)) { $this->connection = 'default'; } - if (strtolower($this->args[0]) == 'all') { + if (strtolower($this->args[0]) === 'all') { return $this->all(); } $model = $this->_modelName($this->args[0]); @@ -149,7 +148,7 @@ class ModelTask extends BakeTask { $object = new Model(array('name' => $className, 'table' => $table, 'ds' => $this->connection)); $fields = $object->schema(true); foreach ($fields as $name => $field) { - if (isset($field['key']) && $field['key'] == 'primary') { + if (isset($field['key']) && $field['key'] === 'primary') { $object->primaryKey = $name; break; } @@ -162,8 +161,8 @@ class ModelTask extends BakeTask { * * @param array $options Array of options to use for the selections. indexes must start at 0 * @param string $prompt Prompt to use for options list. - * @param integer $default The default option for the given prompt. - * @return integer result of user choice. + * @param int $default The default option for the given prompt. + * @return int Result of user choice. */ public function inOptions($options, $prompt = null, $default = null) { $valid = false; @@ -177,7 +176,7 @@ class ModelTask extends BakeTask { $prompt = __d('cake_console', 'Make a selection from the choices above'); } $choice = $this->in($prompt, null, $default); - if (intval($choice) > 0 && intval($choice) <= $max) { + if ((int)$choice > 0 && (int)$choice <= $max) { $valid = true; } } @@ -187,7 +186,7 @@ class ModelTask extends BakeTask { /** * Handles interactive baking * - * @return boolean + * @return bool */ protected function _interactive() { $this->hr(); @@ -208,7 +207,7 @@ class ModelTask extends BakeTask { if (!in_array($useTable, $this->_tables)) { $prompt = __d('cake_console', "The table %s doesn't exist or could not be automatically detected\ncontinue anyway?", $useTable); $continue = $this->in($prompt, array('y', 'n')); - if (strtolower($continue) == 'n') { + if (strtolower($continue) === 'n') { return false; } } @@ -233,14 +232,14 @@ class ModelTask extends BakeTask { } $prompt = __d('cake_console', "Would you like to supply validation criteria \nfor the fields in your model?"); - $wannaDoValidation = $this->in($prompt, array('y','n'), 'y'); - if (array_search($useTable, $this->_tables) !== false && strtolower($wannaDoValidation) == 'y') { + $wannaDoValidation = $this->in($prompt, array('y', 'n'), 'y'); + if (array_search($useTable, $this->_tables) !== false && strtolower($wannaDoValidation) === 'y') { $validate = $this->doValidation($tempModel); } $prompt = __d('cake_console', "Would you like to define model associations\n(hasMany, hasOne, belongsTo, etc.)?"); - $wannaDoAssoc = $this->in($prompt, array('y','n'), 'y'); - if (strtolower($wannaDoAssoc) == 'y') { + $wannaDoAssoc = $this->in($prompt, array('y', 'n'), 'y'); + if (strtolower($wannaDoAssoc) === 'y') { $associations = $this->doAssociations($tempModel); } } @@ -257,7 +256,7 @@ class ModelTask extends BakeTask { if ($fullTableName !== Inflector::tableize($currentModelName)) { $this->out(__d('cake_console', 'DB Table: %s', $fullTableName)); } - if ($primaryKey != 'id') { + if ($primaryKey !== 'id') { $this->out(__d('cake_console', 'Primary Key: %s', $primaryKey)); } if (!empty($validate)) { @@ -274,7 +273,7 @@ class ModelTask extends BakeTask { $this->hr(); $looksGood = $this->in(__d('cake_console', 'Look okay?'), array('y', 'n'), 'y'); - if (strtolower($looksGood) == 'y') { + if (strtolower($looksGood) === 'y') { $vars = compact('associations', 'validate', 'primaryKey', 'useTable', 'displayField'); $vars['useDbConfig'] = $this->connection; if ($this->bake($currentModelName, $vars)) { @@ -314,7 +313,7 @@ class ModelTask extends BakeTask { public function findPrimaryKey($fields) { $name = 'id'; foreach ($fields as $name => $field) { - if (isset($field['key']) && $field['key'] == 'primary') { + if (isset($field['key']) && $field['key'] === 'primary') { break; } } @@ -331,7 +330,7 @@ class ModelTask extends BakeTask { $fieldNames = array_keys($fields); $prompt = __d('cake_console', "A displayField could not be automatically detected\nwould you like to choose one?"); $continue = $this->in($prompt, array('y', 'n')); - if (strtolower($continue) == 'n') { + if (strtolower($continue) === 'n') { return false; } $prompt = __d('cake_console', 'Choose a field from the options above:'); @@ -343,24 +342,33 @@ class ModelTask extends BakeTask { * Handles Generation and user interaction for creating validation. * * @param Model $model Model to have validations generated for. - * @return array $validate Array of user selected validations. + * @return array validate Array of user selected validations. */ public function doValidation($model) { - if (!is_object($model)) { + if (!$model instanceof Model) { return false; } - $fields = $model->schema(); + $fields = $model->schema(); if (empty($fields)) { return false; } + + $skipFields = false; $validate = array(); $this->initValidations(); foreach ($fields as $fieldName => $field) { $validation = $this->fieldValidation($fieldName, $field, $model->primaryKey); + if (isset($validation['_skipFields'])) { + unset($validation['_skipFields']); + $skipFields = true; + } if (!empty($validation)) { $validate[$fieldName] = $validation; } + if ($skipFields) { + return $validate; + } } return $validate; } @@ -375,11 +383,13 @@ class ModelTask extends BakeTask { if (class_exists('Validation')) { $options = get_class_methods('Validation'); } + $deprecatedOptions = array('notEmpty', 'between', 'ssn'); + $options = array_diff($options, $deprecatedOptions); sort($options); $default = 1; - foreach ($options as $key => $option) { - if ($option{0} != '_') { - $choices[$default] = strtolower($option); + foreach ($options as $option) { + if ($option{0} !== '_') { + $choices[$default] = $option; $default++; } } @@ -393,15 +403,20 @@ class ModelTask extends BakeTask { * * @param string $fieldName Name of field to be validated. * @param array $metaData metadata for field - * @param string $primaryKey + * @param string $primaryKey The primary key field. * @return array Array of validation for the field. */ public function fieldValidation($fieldName, $metaData, $primaryKey = 'id') { $defaultChoice = count($this->_validations); $validate = $alreadyChosen = array(); + $prompt = __d('cake_console', + "or enter in a valid regex validation string.\nAlternatively [s] skip the rest of the fields.\n" + ); + $methods = array_flip($this->_validations); + $anotherValidator = 'y'; - while ($anotherValidator == 'y') { + while ($anotherValidator === 'y') { if ($this->interactive) { $this->out(); $this->out(__d('cake_console', 'Field: %s', $fieldName)); @@ -423,35 +438,41 @@ class ModelTask extends BakeTask { $this->hr(); } - $prompt = __d('cake_console', "... or enter in a valid regex validation string.\n"); - $methods = array_flip($this->_validations); $guess = $defaultChoice; if ($metaData['null'] != 1 && !in_array($fieldName, array($primaryKey, 'created', 'modified', 'updated'))) { - if ($fieldName == 'email') { + if ($fieldName === 'email') { $guess = $methods['email']; - } elseif ($metaData['type'] == 'string' && $metaData['length'] == 36) { + } elseif ($metaData['type'] === 'string' && $metaData['length'] == 36) { $guess = $methods['uuid']; - } elseif ($metaData['type'] == 'string') { - $guess = $methods['notempty']; - } elseif ($metaData['type'] == 'text') { - $guess = $methods['notempty']; - } elseif ($metaData['type'] == 'integer') { + } elseif ($metaData['type'] === 'string') { + $guess = $methods['notBlank']; + } elseif ($metaData['type'] === 'text') { + $guess = $methods['notBlank']; + } elseif ($metaData['type'] === 'integer') { $guess = $methods['numeric']; - } elseif ($metaData['type'] == 'boolean') { + } elseif ($metaData['type'] === 'float') { + $guess = $methods['numeric']; + } elseif ($metaData['type'] === 'boolean') { $guess = $methods['boolean']; - } elseif ($metaData['type'] == 'date') { + } elseif ($metaData['type'] === 'date') { $guess = $methods['date']; - } elseif ($metaData['type'] == 'time') { + } elseif ($metaData['type'] === 'time') { $guess = $methods['time']; - } elseif ($metaData['type'] == 'datetime') { + } elseif ($metaData['type'] === 'datetime') { $guess = $methods['datetime']; - } elseif ($metaData['type'] == 'inet') { + } elseif ($metaData['type'] === 'inet') { $guess = $methods['ip']; + } elseif ($metaData['type'] === 'decimal') { + $guess = $methods['decimal']; } } if ($this->interactive === true) { $choice = $this->in($prompt, null, $guess); + if ($choice === 's') { + $validate['_skipFields'] = true; + return $validate; + } if (in_array($choice, $alreadyChosen)) { $this->out(__d('cake_console', "You have already chosen that validation rule,\nplease choose again")); continue; @@ -472,16 +493,19 @@ class ModelTask extends BakeTask { } if ($choice != $defaultChoice) { + $validate[$validatorName] = $choice; if (is_numeric($choice) && isset($this->_validations[$choice])) { $validate[$validatorName] = $this->_validations[$choice]; - } else { - $validate[$validatorName] = $choice; } } - if ($this->interactive == true && $choice != $defaultChoice) { - $anotherValidator = $this->in(__d('cake_console', 'Would you like to add another validation rule?'), array('y', 'n'), 'n'); - } else { - $anotherValidator = 'n'; + $anotherValidator = 'n'; + if ($this->interactive && $choice != $defaultChoice) { + $anotherValidator = $this->in(__d('cake_console', "Would you like to add another validation rule\n" . + "or skip the rest of the fields?"), array('y', 'n', 's'), 'n'); + if ($anotherValidator === 's') { + $validate['_skipFields'] = true; + return $validate; + } } } return $validate; @@ -490,11 +514,11 @@ class ModelTask extends BakeTask { /** * Handles associations * - * @param Model $model - * @return array $associations + * @param Model $model The model object + * @return array Associations */ public function doAssociations($model) { - if (!is_object($model)) { + if (!$model instanceof Model) { return false; } if ($this->interactive === true) { @@ -539,25 +563,49 @@ class ModelTask extends BakeTask { return $associations; } +/** + * Handles behaviors + * + * @param Model $model The model object. + * @return array Behaviors + */ + public function doActsAs($model) { + if (!$model instanceof Model) { + return false; + } + $behaviors = array(); + $fields = $model->schema(true); + if (empty($fields)) { + return array(); + } + + if (isset($fields['lft']) && $fields['lft']['type'] === 'integer' && + isset($fields['rght']) && $fields['rght']['type'] === 'integer' && + isset($fields['parent_id'])) { + $behaviors[] = 'Tree'; + } + return $behaviors; + } + /** * Find belongsTo relations and add them to the associations list. * * @param Model $model Model instance of model being generated. * @param array $associations Array of in progress associations - * @return array $associations with belongsTo added in. + * @return array Associations with belongsTo added in. */ public function findBelongsTo(Model $model, $associations) { - $fields = $model->schema(true); - foreach ($fields as $fieldName => $field) { - $offset = strpos($fieldName, '_id'); - if ($fieldName != $model->primaryKey && $fieldName != 'parent_id' && $offset !== false) { + $fieldNames = array_keys($model->schema(true)); + foreach ($fieldNames as $fieldName) { + $offset = substr($fieldName, -3) === '_id'; + if ($fieldName != $model->primaryKey && $fieldName !== 'parent_id' && $offset !== false) { $tmpModelName = $this->_modelNameFromKey($fieldName); $associations['belongsTo'][] = array( 'alias' => $tmpModelName, 'className' => $tmpModelName, 'foreignKey' => $fieldName, ); - } elseif ($fieldName == 'parent_id') { + } elseif ($fieldName === 'parent_id') { $associations['belongsTo'][] = array( 'alias' => 'Parent' . $model->name, 'className' => $model->name, @@ -569,32 +617,32 @@ class ModelTask extends BakeTask { } /** - * Find the hasOne and HasMany relations and add them to associations list + * Find the hasOne and hasMany relations and add them to associations list * * @param Model $model Model instance being generated * @param array $associations Array of in progress associations - * @return array $associations with hasOne and hasMany added in. + * @return array Associations with hasOne and hasMany added in. */ public function findHasOneAndMany(Model $model, $associations) { $foreignKey = $this->_modelKey($model->name); foreach ($this->_tables as $otherTable) { $tempOtherModel = $this->_getModelObject($this->_modelName($otherTable), $otherTable); - $modelFieldsTemp = $tempOtherModel->schema(true); + $tempFieldNames = array_keys($tempOtherModel->schema(true)); $pattern = '/_' . preg_quote($model->table, '/') . '|' . preg_quote($model->table, '/') . '_/'; $possibleJoinTable = preg_match($pattern, $otherTable); - if ($possibleJoinTable == true) { + if ($possibleJoinTable) { continue; } - foreach ($modelFieldsTemp as $fieldName => $field) { + foreach ($tempFieldNames as $fieldName) { $assoc = false; - if ($fieldName != $model->primaryKey && $fieldName == $foreignKey) { + if ($fieldName !== $model->primaryKey && $fieldName === $foreignKey) { $assoc = array( 'alias' => $tempOtherModel->name, 'className' => $tempOtherModel->name, 'foreignKey' => $fieldName ); - } elseif ($otherTable == $model->table && $fieldName == 'parent_id') { + } elseif ($otherTable === $model->table && $fieldName === 'parent_id') { $assoc = array( 'alias' => 'Child' . $model->name, 'className' => $model->name, @@ -616,29 +664,22 @@ class ModelTask extends BakeTask { * * @param Model $model Model instance being generated * @param array $associations Array of in-progress associations - * @return array $associations with hasAndBelongsToMany added in. + * @return array Associations with hasAndBelongsToMany added in. */ public function findHasAndBelongsToMany(Model $model, $associations) { $foreignKey = $this->_modelKey($model->name); foreach ($this->_tables as $otherTable) { - $tempOtherModel = $this->_getModelObject($this->_modelName($otherTable), $otherTable); - $modelFieldsTemp = $tempOtherModel->schema(true); - + $tableName = null; $offset = strpos($otherTable, $model->table . '_'); $otherOffset = strpos($otherTable, '_' . $model->table); if ($offset !== false) { - $offset = strlen($model->table . '_'); - $habtmName = $this->_modelName(substr($otherTable, $offset)); - $associations['hasAndBelongsToMany'][] = array( - 'alias' => $habtmName, - 'className' => $habtmName, - 'foreignKey' => $foreignKey, - 'associationForeignKey' => $this->_modelKey($habtmName), - 'joinTable' => $otherTable - ); + $tableName = substr($otherTable, strlen($model->table . '_')); } elseif ($otherOffset !== false) { - $habtmName = $this->_modelName(substr($otherTable, 0, $otherOffset)); + $tableName = substr($otherTable, 0, $otherOffset); + } + if ($tableName && in_array($tableName, $this->_tables)) { + $habtmName = $this->_modelName($tableName); $associations['hasAndBelongsToMany'][] = array( 'alias' => $habtmName, 'className' => $habtmName, @@ -665,9 +706,9 @@ class ModelTask extends BakeTask { $prompt = "{$model->name} {$type} {$assoc['alias']}?"; $response = $this->in($prompt, array('y', 'n'), 'y'); - if ('n' == strtolower($response)) { + if (strtolower($response) === 'n') { unset($associations[$type][$i]); - } elseif ($type == 'hasMany') { + } elseif ($type === 'hasMany') { unset($associations['hasOne'][$i]); } } @@ -688,19 +729,19 @@ class ModelTask extends BakeTask { $prompt = __d('cake_console', 'Would you like to define some additional model associations?'); $wannaDoMoreAssoc = $this->in($prompt, array('y', 'n'), 'n'); $possibleKeys = $this->_generatePossibleKeys(); - while (strtolower($wannaDoMoreAssoc) == 'y') { + while (strtolower($wannaDoMoreAssoc) === 'y') { $assocs = array('belongsTo', 'hasOne', 'hasMany', 'hasAndBelongsToMany'); $this->out(__d('cake_console', 'What is the association type?')); - $assocType = intval($this->inOptions($assocs, __d('cake_console', 'Enter a number'))); + $assocType = (int)$this->inOptions($assocs, __d('cake_console', 'Enter a number')); $this->out(__d('cake_console', "For the following options be very careful to match your setup exactly.\n" . "Any spelling mistakes will cause errors.")); $this->hr(); $alias = $this->in(__d('cake_console', 'What is the alias for this association?')); - $className = $this->in(__d('cake_console', 'What className will %s use?', $alias), null, $alias ); + $className = $this->in(__d('cake_console', 'What className will %s use?', $alias), null, $alias); - if ($assocType == 0) { + if ($assocType === 0) { if (!empty($possibleKeys[$model->table])) { $showKeys = $possibleKeys[$model->table]; } else { @@ -728,12 +769,12 @@ class ModelTask extends BakeTask { if (!empty($showKeys)) { $this->out(__d('cake_console', 'A helpful List of possible keys')); $foreignKey = $this->inOptions($showKeys, __d('cake_console', 'What is the foreignKey?')); - $foreignKey = $showKeys[intval($foreignKey)]; + $foreignKey = $showKeys[(int)$foreignKey]; } if (!isset($foreignKey)) { $foreignKey = $this->in(__d('cake_console', 'What is the foreignKey? Specify your own.'), null, $suggestedForeignKey); } - if ($assocType == 3) { + if ($assocType === 3) { $associationForeignKey = $this->in(__d('cake_console', 'What is the associationForeignKey?'), null, $this->_modelKey($model->name)); $joinTable = $this->in(__d('cake_console', 'What is the joinTable?')); } @@ -743,7 +784,7 @@ class ModelTask extends BakeTask { $associations[$assocs[$assocType]][$i]['alias'] = $alias; $associations[$assocs[$assocType]][$i]['className'] = $className; $associations[$assocs[$assocType]][$i]['foreignKey'] = $foreignKey; - if ($assocType == 3) { + if ($assocType === 3) { $associations[$assocs[$assocType]][$i]['associationForeignKey'] = $associationForeignKey; $associations[$assocs[$assocType]][$i]['joinTable'] = $joinTable; } @@ -755,7 +796,7 @@ class ModelTask extends BakeTask { /** * Finds all possible keys to use on custom associations. * - * @return array array of tables and possible keys + * @return array Array of tables and possible keys */ protected function _generatePossibleKeys() { $possible = array(); @@ -763,7 +804,7 @@ class ModelTask extends BakeTask { $tempOtherModel = new Model(array('table' => $otherTable, 'ds' => $this->connection)); $modelFieldsTemp = $tempOtherModel->schema(true); foreach ($modelFieldsTemp as $fieldName => $field) { - if ($field['type'] == 'integer' || $field['type'] == 'string') { + if ($field['type'] === 'integer' || $field['type'] === 'string') { $possible[$otherTable][] = $fieldName; } } @@ -775,15 +816,16 @@ class ModelTask extends BakeTask { * Assembles and writes a Model file. * * @param string|object $name Model name or object - * @param array|boolean $data if array and $name is not an object assume bake data, otherwise boolean. + * @param array|bool $data if array and $name is not an object assume bake data, otherwise boolean. * @return string */ public function bake($name, $data = array()) { - if (is_object($name)) { - if ($data == false) { + if ($name instanceof Model) { + if (!$data) { $data = array(); $data['associations'] = $this->doAssociations($name); $data['validate'] = $this->doValidation($name); + $data['actsAs'] = $this->doActsAs($name); } $data['primaryKey'] = $name->primaryKey; $data['useTable'] = $name->table; @@ -792,8 +834,10 @@ class ModelTask extends BakeTask { } else { $data['name'] = $name; } + $defaults = array( 'associations' => array(), + 'actsAs' => array(), 'validate' => array(), 'primaryKey' => 'id', 'useTable' => null, @@ -842,7 +886,7 @@ class ModelTask extends BakeTask { * @return array */ public function listAll($useDbConfig = null) { - $this->_tables = (array)$this->getAllTables($useDbConfig); + $this->_tables = $this->getAllTables($useDbConfig); $this->_modelNames = array(); $count = count($this->_tables); @@ -885,8 +929,8 @@ class ModelTask extends BakeTask { $this->out(__d('cake_console', "Given your model named '%s',\nCake would expect a database table named '%s'", $modelName, $fullTableName)); $tableIsGood = $this->in(__d('cake_console', 'Do you want to use this table?'), array('y', 'n'), 'y'); } - if (strtolower($tableIsGood) == 'n') { - $useTable = $this->in(__d('cake_console', 'What is the name of the table?')); + if (strtolower($tableIsGood) === 'n') { + $useTable = $this->in(__d('cake_console', 'What is the name of the table (without prefix)?')); } } return $useTable; @@ -919,8 +963,9 @@ class ModelTask extends BakeTask { } if (empty($tables)) { $this->err(__d('cake_console', 'Your database does not have any tables.')); - $this->_stop(); + return $this->_stop(); } + sort($tables); return $tables; } @@ -928,56 +973,66 @@ class ModelTask extends BakeTask { * Forces the user to specify the model he wants to bake, and returns the selected model name. * * @param string $useDbConfig Database config name - * @return string the model name + * @return string The model name */ public function getName($useDbConfig = null) { $this->listAll($useDbConfig); $enteredModel = ''; - while ($enteredModel == '') { + while (!$enteredModel) { $enteredModel = $this->in(__d('cake_console', "Enter a number from the list above,\n" . "type in the name of another model, or 'q' to exit"), null, 'q'); if ($enteredModel === 'q') { $this->out(__d('cake_console', 'Exit')); - $this->_stop(); + return $this->_stop(); } - if ($enteredModel == '' || intval($enteredModel) > count($this->_modelNames)) { + if (!$enteredModel || (int)$enteredModel > count($this->_modelNames)) { $this->err(__d('cake_console', "The model name you supplied was empty,\n" . "or the number you selected was not an option. Please try again.")); $enteredModel = ''; } } - if (intval($enteredModel) > 0 && intval($enteredModel) <= count($this->_modelNames)) { - $currentModelName = $this->_modelNames[intval($enteredModel) - 1]; - } else { - $currentModelName = $enteredModel; + if ((int)$enteredModel > 0 && (int)$enteredModel <= count($this->_modelNames)) { + return $this->_modelNames[(int)$enteredModel - 1]; } - return $currentModelName; + + return $enteredModel; } /** - * get the option parser. + * Gets the option parser instance and configures it. * - * @return void + * @return ConsoleOptionParser */ public function getOptionParser() { $parser = parent::getOptionParser(); - return $parser->description( - __d('cake_console', 'Bake models.') - )->addArgument('name', array( - 'help' => __d('cake_console', 'Name of the model to bake. Can use Plugin.name to bake plugin models.') - ))->addSubcommand('all', array( - 'help' => __d('cake_console', 'Bake all model files with associations and validation.') - ))->addOption('plugin', array( - 'short' => 'p', - 'help' => __d('cake_console', 'Plugin to bake the model into.') - ))->addOption('connection', array( - 'short' => 'c', - 'help' => __d('cake_console', 'The connection the model table is on.') - ))->epilog(__d('cake_console', 'Omitting all arguments and options will enter into an interactive mode.')); + + $parser->description( + __d('cake_console', 'Bake models.') + )->addArgument('name', array( + 'help' => __d('cake_console', 'Name of the model to bake. Can use Plugin.name to bake plugin models.') + ))->addSubcommand('all', array( + 'help' => __d('cake_console', 'Bake all model files with associations and validation.') + ))->addOption('plugin', array( + 'short' => 'p', + 'help' => __d('cake_console', 'Plugin to bake the model into.') + ))->addOption('theme', array( + 'short' => 't', + 'help' => __d('cake_console', 'Theme to use when baking code.') + ))->addOption('connection', array( + 'short' => 'c', + 'help' => __d('cake_console', 'The connection the model table is on.') + ))->addOption('force', array( + 'short' => 'f', + 'help' => __d('cake_console', 'Force overwriting existing files without prompting.') + ))->epilog( + __d('cake_console', 'Omitting all arguments and options will enter into an interactive mode.') + ); + + return $parser; } /** diff --git a/lib/Cake/Console/Command/Task/PluginTask.php b/lib/Cake/Console/Command/Task/PluginTask.php index 2f972b6..7cd5079 100644 --- a/lib/Cake/Console/Command/Task/PluginTask.php +++ b/lib/Cake/Console/Command/Task/PluginTask.php @@ -1,19 +1,16 @@ out(__d('cake_console', 'Plugin: %s already exists, no action taken', $plugin)); $this->out(__d('cake_console', 'Path: %s', $pluginPath)); return false; - } else { - $this->_interactive($plugin); } + $this->_interactive($plugin); } else { return $this->_interactive(); } @@ -75,7 +71,7 @@ class PluginTask extends AppShell { /** * Interactive interface * - * @param string $plugin + * @param string $plugin The plugin name. * @return void */ protected function _interactive($plugin = null) { @@ -92,7 +88,7 @@ class PluginTask extends AppShell { * Bake the plugin, create directories and files * * @param string $plugin Name of the plugin in CamelCased format - * @return boolean + * @return bool */ public function bake($plugin) { $pathOptions = App::path('plugins'); @@ -106,28 +102,35 @@ class PluginTask extends AppShell { $looksGood = $this->in(__d('cake_console', 'Look okay?'), array('y', 'n', 'q'), 'y'); - if (strtolower($looksGood) == 'y') { + if (strtolower($looksGood) === 'y') { $Folder = new Folder($this->path . $plugin); $directories = array( 'Config' . DS . 'Schema', - 'Model' . DS . 'Behavior', - 'Model' . DS . 'Datasource', 'Console' . DS . 'Command' . DS . 'Task', + 'Console' . DS . 'Templates', 'Controller' . DS . 'Component', 'Lib', - 'View' . DS . 'Helper', + 'Locale' . DS . 'eng' . DS . 'LC_MESSAGES', + 'Model' . DS . 'Behavior', + 'Model' . DS . 'Datasource', 'Test' . DS . 'Case' . DS . 'Controller' . DS . 'Component', - 'Test' . DS . 'Case' . DS . 'View' . DS . 'Helper', + 'Test' . DS . 'Case' . DS . 'Lib', 'Test' . DS . 'Case' . DS . 'Model' . DS . 'Behavior', + 'Test' . DS . 'Case' . DS . 'Model' . DS . 'Datasource', + 'Test' . DS . 'Case' . DS . 'View' . DS . 'Helper', 'Test' . DS . 'Fixture', - 'Vendor', - 'webroot' + 'View' . DS . 'Elements', + 'View' . DS . 'Helper', + 'View' . DS . 'Layouts', + 'webroot' . DS . 'css', + 'webroot' . DS . 'js', + 'webroot' . DS . 'img', ); foreach ($directories as $directory) { $dirPath = $this->path . $plugin . DS . $directory; $Folder->create($dirPath); - $File = new File($dirPath . DS . 'empty', true); + new File($dirPath . DS . 'empty', true); } foreach ($Folder->messages() as $message) { @@ -145,15 +148,17 @@ class PluginTask extends AppShell { $controllerFileName = $plugin . 'AppController.php'; $out = "createFile($this->path . $plugin . DS . 'Controller' . DS . $controllerFileName, $out); $modelFileName = $plugin . 'AppModel.php'; $out = "createFile($this->path . $plugin . DS . 'Model' . DS . $modelFileName, $out); $this->_modifyBootstrap($plugin); @@ -168,6 +173,7 @@ class PluginTask extends AppShell { /** * Update the app's bootstrap.php file. * + * @param string $plugin Name of plugin * @return void */ protected function _modifyBootstrap($plugin) { @@ -183,16 +189,18 @@ class PluginTask extends AppShell { /** * find and change $this->path to the user selection * - * @param array $pathOptions - * @return string plugin path + * @param array $pathOptions The list of paths to look in. + * @return void */ public function findPath($pathOptions) { $valid = false; foreach ($pathOptions as $i => $path) { if (!is_dir($path)) { - array_splice($pathOptions, $i, 1); + unset($pathOptions[$i]); } } + $pathOptions = array_values($pathOptions); + $max = count($pathOptions); while (!$valid) { foreach ($pathOptions as $i => $option) { @@ -200,7 +208,7 @@ class PluginTask extends AppShell { } $prompt = __d('cake_console', 'Choose a plugin path from the paths above.'); $choice = $this->in($prompt, null, 1); - if (intval($choice) > 0 && intval($choice) <= $max) { + if ((int)$choice > 0 && (int)$choice <= $max) { $valid = true; } } @@ -208,18 +216,21 @@ class PluginTask extends AppShell { } /** - * get the option parser for the plugin task + * Gets the option parser instance and configures it. * - * @return void + * @return ConsoleOptionParser */ public function getOptionParser() { $parser = parent::getOptionParser(); - return $parser->description(__d('cake_console', - 'Create the directory structure, AppModel and AppController classes for a new plugin. ' . - 'Can create plugins in any of your bootstrapped plugin paths.' - ))->addArgument('name', array( + + $parser->description( + __d('cake_console', 'Create the directory structure, AppModel and AppController classes for a new plugin. ' . + 'Can create plugins in any of your bootstrapped plugin paths.') + )->addArgument('name', array( 'help' => __d('cake_console', 'CamelCased name of the plugin to create.') )); + + return $parser; } } diff --git a/lib/Cake/Console/Command/Task/ProjectTask.php b/lib/Cake/Console/Command/Task/ProjectTask.php index ebfe4e9..df1ab19 100644 --- a/lib/Cake/Console/Command/Task/ProjectTask.php +++ b/lib/Cake/Console/Command/Task/ProjectTask.php @@ -2,25 +2,23 @@ /** * The Project Task handles creating the base application * - * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @since CakePHP(tm) v 1.2 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ App::uses('AppShell', 'Console/Command'); App::uses('File', 'Utility'); App::uses('Folder', 'Utility'); -App::uses('String', 'Utility'); +App::uses('CakeText', 'Utility'); App::uses('Security', 'Utility'); /** @@ -66,7 +64,7 @@ class ProjectTask extends AppShell { } $response = false; - while ($response == false && is_dir($project) === true && file_exists($project . 'Config' . 'core.php')) { + while (!$response && is_dir($project) === true && file_exists($project . 'Config' . 'core.php')) { $prompt = __d('cake_console', 'A project already exists in this location: %s Overwrite?', $project); $response = $this->in($prompt, array('y', 'n'), 'n'); if (strtolower($response) === 'n') { @@ -92,6 +90,13 @@ class ProjectTask extends AppShell { $success = false; } + if ($this->cachePrefix($path)) { + $this->out(__d('cake_console', ' * Cache prefix set')); + } else { + $this->err(__d('cake_console', 'The cache prefix was NOT set')); + $success = false; + } + if ($this->consolePath($path) === true) { $this->out(__d('cake_console', ' * app/Console/cake.php path set.')); } else { @@ -109,8 +114,8 @@ class ProjectTask extends AppShell { } $success = $this->corePath($path, $hardCode) === true; if ($success) { - $this->out(__d('cake_console', ' * CAKE_CORE_INCLUDE_PATH set to %s in webroot/index.php', CAKE_CORE_INCLUDE_PATH)); - $this->out(__d('cake_console', ' * CAKE_CORE_INCLUDE_PATH set to %s in webroot/test.php', CAKE_CORE_INCLUDE_PATH)); + $this->out(__d('cake_console', ' * CAKE_CORE_INCLUDE_PATH set to %s in %s', CAKE_CORE_INCLUDE_PATH, 'webroot/index.php')); + $this->out(__d('cake_console', ' * CAKE_CORE_INCLUDE_PATH set to %s in %s', CAKE_CORE_INCLUDE_PATH, 'webroot/test.php')); } else { $this->err(__d('cake_console', 'Unable to set CAKE_CORE_INCLUDE_PATH, you should change it in %s', $path . 'webroot' . DS . 'index.php')); $success = false; @@ -122,7 +127,7 @@ class ProjectTask extends AppShell { $Folder = new Folder($path); if (!$Folder->chmod($path . 'tmp', 0777)) { $this->err(__d('cake_console', 'Could not set permissions on %s', $path . DS . 'tmp')); - $this->out(__d('cake_console', 'chmod -R 0777 %s', $path . DS . 'tmp')); + $this->out('chmod -R 0777 ' . $path . DS . 'tmp'); $success = false; } if ($success) { @@ -137,7 +142,7 @@ class ProjectTask extends AppShell { /** * Checks PHP's include_path for CakePHP. * - * @return boolean Indicates whether or not CakePHP exists on include_path + * @return bool Indicates whether or not CakePHP exists on include_path */ public function cakeOnIncludePath() { $paths = explode(PATH_SEPARATOR, ini_get('include_path')); @@ -207,7 +212,7 @@ class ProjectTask extends AppShell { } foreach ($Folder->messages() as $message) { - $this->out(String::wrap(' * ' . $message), 1, Shell::VERBOSE); + $this->out(CakeText::wrap(' * ' . $message), 1, Shell::VERBOSE); } return true; @@ -226,14 +231,14 @@ class ProjectTask extends AppShell { * and points app/console/cake.php to the right place * * @param string $path Project path. - * @return boolean success + * @return bool success */ public function consolePath($path) { $File = new File($path . 'Console' . DS . 'cake.php'); $contents = $File->read(); if (preg_match('/(__CAKE_PATH__)/', $contents, $match)) { - $root = strpos(CAKE_CORE_INCLUDE_PATH, '/') === 0 ? " \$ds . '" : "'"; - $replacement = $root . str_replace(DS, "' . \$ds . '", trim(CAKE_CORE_INCLUDE_PATH, DS)) . "'"; + $root = strpos(CAKE_CORE_INCLUDE_PATH, '/') === 0 ? " DS . '" : "'"; + $replacement = $root . str_replace(DS, "' . DS . '", trim(CAKE_CORE_INCLUDE_PATH, DS)) . "'"; $result = str_replace($match[0], $replacement, $contents); if ($File->write($result)) { return true; @@ -247,7 +252,7 @@ class ProjectTask extends AppShell { * Generates and writes 'Security.salt' * * @param string $path Project path - * @return boolean Success + * @return bool Success */ public function securitySalt($path) { $File = new File($path . 'Config' . DS . 'core.php'); @@ -267,7 +272,7 @@ class ProjectTask extends AppShell { * Generates and writes 'Security.cipherSeed' * * @param string $path Project path - * @return boolean Success + * @return bool Success */ public function securityCipherSeed($path) { $File = new File($path . 'Config' . DS . 'core.php'); @@ -284,12 +289,29 @@ class ProjectTask extends AppShell { return false; } +/** + * Writes cache prefix using app's name + * + * @param string $dir Path to project + * @return bool Success + */ + public function cachePrefix($dir) { + $app = basename($dir); + $File = new File($dir . 'Config' . DS . 'core.php'); + $contents = $File->read(); + if (preg_match('/(\$prefix = \'myapp_\';)/', $contents, $match)) { + $result = str_replace($match[0], '$prefix = \'' . $app . '_\';', $contents); + return $File->write($result); + } + return false; + } + /** * Generates and writes CAKE_CORE_INCLUDE_PATH * * @param string $path Project path - * @param boolean $hardCode Wether or not define calls should be hardcoded. - * @return boolean Success + * @param bool $hardCode Whether or not define calls should be hardcoded. + * @return bool Success */ public function corePath($path, $hardCode = true) { if (dirname($path) !== CAKE_CORE_INCLUDE_PATH) { @@ -309,8 +331,8 @@ class ProjectTask extends AppShell { * Replaces the __CAKE_PATH__ placeholder in the template files. * * @param string $filename The filename to operate on. - * @param boolean $hardCode Whether or not the define should be uncommented. - * @return boolean Success + * @param bool $hardCode Whether or not the define should be uncommented. + * @return bool Success */ protected function _replaceCorePath($filename, $hardCode) { $contents = file_get_contents($filename); @@ -318,6 +340,11 @@ class ProjectTask extends AppShell { $root = strpos(CAKE_CORE_INCLUDE_PATH, '/') === 0 ? " DS . '" : "'"; $corePath = $root . str_replace(DS, "' . DS . '", trim(CAKE_CORE_INCLUDE_PATH, DS)) . "'"; + $composer = ROOT . DS . APP_DIR . DS . 'Vendor' . DS . 'cakephp' . DS . 'cakephp' . DS . 'lib'; + if (file_exists($composer)) { + $corePath = " ROOT . DS . APP_DIR . DS . 'Vendor' . DS . 'cakephp' . DS . 'cakephp' . DS . 'lib'"; + } + $result = str_replace('__CAKE_PATH__', $corePath, $contents, $count); if ($hardCode) { $result = str_replace('//define(\'CAKE_CORE', 'define(\'CAKE_CORE', $result); @@ -325,17 +352,14 @@ class ProjectTask extends AppShell { if (!file_put_contents($filename, $result)) { return false; } - if ($count == 0) { - return false; - } - return true; + return (bool)$count; } /** * Enables Configure::read('Routing.prefixes') in /app/Config/core.php * * @param string $name Name to use as admin routing - * @return boolean Success + * @return bool Success */ public function cakeAdmin($name) { $path = (empty($this->configPath)) ? APP . 'Config' . DS : $this->configPath; @@ -346,12 +370,9 @@ class ProjectTask extends AppShell { if ($File->write($result)) { Configure::write('Routing.prefixes', array($name)); return true; - } else { - return false; } - } else { - return false; } + return false; } /** @@ -363,7 +384,7 @@ class ProjectTask extends AppShell { $admin = ''; $prefixes = Configure::read('Routing.prefixes'); if (!empty($prefixes)) { - if (count($prefixes) == 1) { + if (count($prefixes) === 1) { return $prefixes[0] . '_'; } if ($this->interactive) { @@ -382,16 +403,20 @@ class ProjectTask extends AppShell { } if ($this->interactive) { $this->hr(); - $this->out(__d('cake_console', 'You need to enable Configure::write(\'Routing.prefixes\',array(\'admin\')) in /app/Config/core.php to use prefix routing.')); + $this->out(__d('cake_console', 'You need to enable %s in %s to use prefix routing.', + 'Configure::write(\'Routing.prefixes\', array(\'admin\'))', + '/app/Config/core.php')); $this->out(__d('cake_console', 'What would you like the prefix route to be?')); - $this->out(__d('cake_console', 'Example: www.example.com/admin/controller')); - while ($admin == '') { + $this->out(__d('cake_console', 'Example: %s', 'www.example.com/admin/controller')); + while (!$admin) { $admin = $this->in(__d('cake_console', 'Enter a routing prefix:'), null, 'admin'); } if ($this->cakeAdmin($admin) !== true) { - $this->out(__d('cake_console', 'Unable to write to /app/Config/core.php.')); - $this->out(__d('cake_console', 'You need to enable Configure::write(\'Routing.prefixes\',array(\'admin\')) in /app/Config/core.php to use prefix routing.')); - $this->_stop(); + $this->out(__d('cake_console', 'Unable to write to %s.', '/app/Config/core.php')); + $this->out(__d('cake_console', 'You need to enable %s in %s to use prefix routing.', + 'Configure::write(\'Routing.prefixes\', array(\'admin\'))', + '/app/Config/core.php')); + return $this->_stop(); } return $admin . '_'; } @@ -399,23 +424,30 @@ class ProjectTask extends AppShell { } /** - * get the option parser. + * Gets the option parser instance and configures it. * * @return ConsoleOptionParser */ public function getOptionParser() { $parser = parent::getOptionParser(); - return $parser->description( - __d('cake_console', 'Generate a new CakePHP project skeleton.') - )->addArgument('name', array( - 'help' => __d('cake_console', 'Application directory to make, if it starts with "/" the path is absolute.') - ))->addOption('empty', array( - 'boolean' => true, - 'help' => __d('cake_console', 'Create empty files in each of the directories. Good if you are using git') - ))->addOption('skel', array( - 'default' => current(App::core('Console')) . 'Templates' . DS . 'skel', - 'help' => __d('cake_console', 'The directory layout to use for the new application skeleton. Defaults to cake/Console/Templates/skel of CakePHP used to create the project.') - )); + + $parser->description( + __d('cake_console', 'Generate a new CakePHP project skeleton.') + )->addArgument('name', array( + 'help' => __d('cake_console', 'Application directory to make, if it starts with "/" the path is absolute.') + ))->addOption('empty', array( + 'boolean' => true, + 'help' => __d('cake_console', 'Create empty files in each of the directories. Good if you are using git') + ))->addOption('theme', array( + 'short' => 't', + 'help' => __d('cake_console', 'Theme to use when baking code.') + ))->addOption('skel', array( + 'default' => current(App::core('Console')) . 'Templates' . DS . 'skel', + 'help' => __d('cake_console', 'The directory layout to use for the new application skeleton.' . + ' Defaults to cake/Console/Templates/skel of CakePHP used to create the project.') + )); + + return $parser; } } diff --git a/lib/Cake/Console/Command/Task/TemplateTask.php b/lib/Cake/Console/Command/Task/TemplateTask.php index 6efa8bb..d5dfc44 100644 --- a/lib/Cake/Console/Command/Task/TemplateTask.php +++ b/lib/Cake/Console/Command/Task/TemplateTask.php @@ -2,18 +2,17 @@ /** * Template Task can generate templated output Used in other Tasks * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @since CakePHP(tm) v 1.3 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ App::uses('AppShell', 'Console/Command'); @@ -43,7 +42,7 @@ class TemplateTask extends AppShell { public $templatePaths = array(); /** - * Initialize callback. Setup paths for the template task. + * Initialize callback. Setup paths for the template task. * * @return void */ @@ -122,7 +121,7 @@ class TemplateTask extends AppShell { $data = array($one => $two); } - if ($data == null) { + if (!$data) { return false; } $this->templateVars = $data + $this->templateVars; @@ -165,7 +164,7 @@ class TemplateTask extends AppShell { * @return string returns the path to the selected theme. */ public function getThemePath() { - if (count($this->templatePaths) == 1) { + if (count($this->templatePaths) === 1) { $paths = array_values($this->templatePaths); return $paths[0]; } diff --git a/lib/Cake/Console/Command/Task/TestTask.php b/lib/Cake/Console/Command/Task/TestTask.php index 0a7b53f..7b5cc54 100644 --- a/lib/Cake/Console/Command/Task/TestTask.php +++ b/lib/Cake/Console/Command/Task/TestTask.php @@ -2,18 +2,17 @@ /** * The TestTask handles creating and updating test files. * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @since CakePHP(tm) v 1.3 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ App::uses('AppShell', 'Console/Command'); @@ -83,15 +82,16 @@ class TestTask extends BakeTask { */ public function execute() { parent::execute(); - if (empty($this->args)) { + $count = count($this->args); + if (!$count) { $this->_interactive(); } - if (count($this->args) == 1) { + if ($count === 1) { $this->_interactive($this->args[0]); } - if (count($this->args) > 1) { + if ($count > 1) { $type = Inflector::classify($this->args[0]); if ($this->bake($type, $this->args[1])) { $this->out('Done'); @@ -102,8 +102,8 @@ class TestTask extends BakeTask { /** * Handles interactive baking * - * @param string $type - * @return string|boolean + * @param string $type The type of object to bake a test for. + * @return string|bool */ protected function _interactive($type = null) { $this->interactive = true; @@ -129,7 +129,7 @@ class TestTask extends BakeTask { * * @param string $type Type of object to bake test case for ie. Model, Controller * @param string $className the 'cake name' for the class ie. Posts for the PostsController - * @return string|boolean + * @return string|bool */ public function bake($type, $className) { $plugin = null; @@ -196,7 +196,7 @@ class TestTask extends BakeTask { } $keys[] = 'q'; $selection = $this->in(__d('cake_console', 'Enter the type of object to bake a test for or (q)uit'), $keys, 'q'); - if ($selection == 'q') { + if ($selection === 'q') { return $this->_stop(); } $types = array_keys($this->classTypes); @@ -242,7 +242,7 @@ class TestTask extends BakeTask { * Currently only model, and controller are supported * * @param string $type The Type of object you are generating tests for eg. controller - * @return boolean + * @return bool */ public function typeCanDetectFixtures($type) { $type = strtolower($type); @@ -254,7 +254,7 @@ class TestTask extends BakeTask { * * @param string $package The package of object you are generating tests for eg. controller * @param string $class the Classname of the class the test is being generated for. - * @return boolean + * @return bool */ public function isLoadableClass($package, $class) { App::uses($class, $package); @@ -275,11 +275,11 @@ class TestTask extends BakeTask { * @param string $class the Classname of the class the test is being generated for. * @return object And instance of the class that is going to be tested. */ - public function &buildTestSubject($type, $class) { + public function buildTestSubject($type, $class) { ClassRegistry::flush(); - App::import($type, $class); + App::uses($class, $type); $class = $this->getRealClassName($type, $class); - if (strtolower($type) == 'model') { + if (strtolower($type) === 'model') { $instance = ClassRegistry::init($class); } else { $instance = new $class(); @@ -293,16 +293,16 @@ class TestTask extends BakeTask { * * @param string $type The Type of object you are generating tests for eg. controller * @param string $class the Classname of the class the test is being generated for. - * @return string Real classname + * @return string Real class name */ public function getRealClassName($type, $class) { - if (strtolower($type) == 'model' || empty($this->classTypes[$type])) { + if (strtolower($type) === 'model' || empty($this->classTypes[$type])) { return $class; } $position = strpos($class, $type); - if ($position !== false && strlen($class) - $position == strlen($type)) { + if ($position !== false && (strlen($class) - $position) === strlen($type)) { return $class; } return $class . $type; @@ -334,7 +334,7 @@ class TestTask extends BakeTask { * @param string $type The type the class having a test * generated for is in. * @return array Array of (class, type) - * @throws CakeException On invalid typename + * @throws CakeException on invalid types. */ public function getBaseType($type) { if (empty($this->baseTypes[$type])) { @@ -356,7 +356,7 @@ class TestTask extends BakeTask { $thisMethods = array_diff($classMethods, $parentMethods); $out = array(); foreach ($thisMethods as $method) { - if (substr($method, 0, 1) != '_' && $method != strtolower($className)) { + if (substr($method, 0, 1) !== '_' && $method != strtolower($className)) { $out[] = $method; } } @@ -367,14 +367,14 @@ class TestTask extends BakeTask { * Generate the list of fixtures that will be required to run this test based on * loaded models. * - * @param object $subject The object you want to generate fixtures for. + * @param CakeObject $subject The object you want to generate fixtures for. * @return array Array of fixtures to be included in the test. */ public function generateFixtureList($subject) { $this->_fixtures = array(); - if (is_a($subject, 'Model')) { + if ($subject instanceof Model) { $this->_processModel($subject); - } elseif (is_a($subject, 'Controller')) { + } elseif ($subject instanceof Controller) { $this->_processController($subject); } return array_values($this->_fixtures); @@ -395,9 +395,9 @@ class TestTask extends BakeTask { if (!isset($this->_fixtures[$className])) { $this->_processModel($subject->{$alias}); } - if ($type == 'hasAndBelongsToMany') { + if ($type === 'hasAndBelongsToMany') { if (!empty($subject->hasAndBelongsToMany[$alias]['with'])) { - list($plugin, $joinModel) = pluginSplit($subject->hasAndBelongsToMany[$alias]['with']); + list(, $joinModel) = pluginSplit($subject->hasAndBelongsToMany[$alias]['with']); } else { $joinModel = Inflector::classify($subject->hasAndBelongsToMany[$alias]['joinTable']); } @@ -422,13 +422,13 @@ class TestTask extends BakeTask { $models = $subject->uses; } foreach ($models as $model) { - list($plugin, $model) = pluginSplit($model); + list(, $model) = pluginSplit($model); $this->_processModel($subject->{$model}); } } /** - * Add classname to the fixture list. + * Add class name to the fixture list. * Sets the app. or plugin.plugin_name. prefix. * * @param string $name Name of the Model class that a fixture might be required for. @@ -452,7 +452,7 @@ class TestTask extends BakeTask { public function getUserFixtures() { $proceed = $this->in(__d('cake_console', 'Bake could not detect fixtures, would you like to add some?'), array('y', 'n'), 'n'); $fixtures = array(); - if (strtolower($proceed) == 'y') { + if (strtolower($proceed) === 'y') { $fixtureList = $this->in(__d('cake_console', "Please provide a comma separated list of the fixtures names you'd like to use.\nExample: 'app.comment, app.post, plugin.forums.post'")); $fixtureListTrimmed = str_replace(' ', '', $fixtureList); $fixtures = explode(',', $fixtureListTrimmed); @@ -466,15 +466,15 @@ class TestTask extends BakeTask { * Controllers require a mock class. * * @param string $type The type of object tests are being generated for eg. controller. - * @return boolean + * @return bool */ public function hasMockClass($type) { $type = strtolower($type); - return $type == 'controller'; + return $type === 'controller'; } /** - * Generate a constructor code snippet for the type and classname + * Generate a constructor code snippet for the type and class name * * @param string $type The Type of object you are generating tests for eg. controller * @param string $fullClassName The Classname of the class the test is being generated for. @@ -484,17 +484,17 @@ class TestTask extends BakeTask { public function generateConstructor($type, $fullClassName, $plugin) { $type = strtolower($type); $pre = $construct = $post = ''; - if ($type == 'model') { + if ($type === 'model') { $construct = "ClassRegistry::init('{$plugin}$fullClassName');\n"; } - if ($type == 'behavior') { + if ($type === 'behavior') { $construct = "new $fullClassName();\n"; } - if ($type == 'helper') { + if ($type === 'helper') { $pre = "\$View = new View();\n"; $construct = "new {$fullClassName}(\$View);\n"; } - if ($type == 'component') { + if ($type === 'component') { $pre = "\$Collection = new ComponentCollection();\n"; $construct = "new {$fullClassName}(\$Collection);\n"; } @@ -502,7 +502,7 @@ class TestTask extends BakeTask { } /** - * Generate the uses() calls for a type & classname + * Generate the uses() calls for a type & class name * * @param string $type The Type of object you are generating tests for eg. controller * @param string $realType The package name for the class. @@ -512,11 +512,11 @@ class TestTask extends BakeTask { public function generateUses($type, $realType, $className) { $uses = array(); $type = strtolower($type); - if ($type == 'component') { + if ($type === 'component') { $uses[] = array('ComponentCollection', 'Controller'); $uses[] = array('Component', 'Controller'); } - if ($type == 'helper') { + if ($type === 'helper') { $uses[] = array('View', 'View'); $uses[] = array('Helper', 'View'); } @@ -543,28 +543,40 @@ class TestTask extends BakeTask { } /** - * get the option parser. + * Gets the option parser instance and configures it. * - * @return void + * @return ConsoleOptionParser */ public function getOptionParser() { $parser = parent::getOptionParser(); - return $parser->description(__d('cake_console', 'Bake test case skeletons for classes.')) - ->addArgument('type', array( - 'help' => __d('cake_console', 'Type of class to bake, can be any of the following: controller, model, helper, component or behavior.'), - 'choices' => array( - 'Controller', 'controller', - 'Model', 'model', - 'Helper', 'helper', - 'Component', 'component', - 'Behavior', 'behavior' - ) - ))->addArgument('name', array( - 'help' => __d('cake_console', 'An existing class to bake tests for.') - ))->addOption('plugin', array( - 'short' => 'p', - 'help' => __d('cake_console', 'CamelCased name of the plugin to bake tests for.') - ))->epilog(__d('cake_console', 'Omitting all arguments and options will enter into an interactive mode.')); + + $parser->description( + __d('cake_console', 'Bake test case skeletons for classes.') + )->addArgument('type', array( + 'help' => __d('cake_console', 'Type of class to bake, can be any of the following: controller, model, helper, component or behavior.'), + 'choices' => array( + 'Controller', 'controller', + 'Model', 'model', + 'Helper', 'helper', + 'Component', 'component', + 'Behavior', 'behavior' + ) + ))->addArgument('name', array( + 'help' => __d('cake_console', 'An existing class to bake tests for.') + ))->addOption('theme', array( + 'short' => 't', + 'help' => __d('cake_console', 'Theme to use when baking code.') + ))->addOption('plugin', array( + 'short' => 'p', + 'help' => __d('cake_console', 'CamelCased name of the plugin to bake tests for.') + ))->addOption('force', array( + 'short' => 'f', + 'help' => __d('cake_console', 'Force overwriting existing files without prompting.') + ))->epilog( + __d('cake_console', 'Omitting all arguments and options will enter into an interactive mode.') + ); + + return $parser; } } diff --git a/lib/Cake/Console/Command/Task/ViewTask.php b/lib/Cake/Console/Command/Task/ViewTask.php index 8baf426..06ecf00 100644 --- a/lib/Cake/Console/Command/Task/ViewTask.php +++ b/lib/Cake/Console/Command/Task/ViewTask.php @@ -2,18 +2,17 @@ /** * The View Tasks handles creating and updating view files. * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @since CakePHP(tm) v 1.2 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ App::uses('AppShell', 'Console/Command'); @@ -63,7 +62,7 @@ class ViewTask extends BakeTask { public $scaffoldActions = array('index', 'view', 'add', 'edit'); /** - * An array of action names that don't require templates. These + * An array of action names that don't require templates. These * actions will not emit errors when doing bakeActions() * * @var array @@ -90,7 +89,7 @@ class ViewTask extends BakeTask { $this->_interactive(); } if (empty($this->args[0])) { - return; + return null; } if (!isset($this->connection)) { $this->connection = 'default'; @@ -99,7 +98,7 @@ class ViewTask extends BakeTask { $this->controllerName = $this->_controllerName($this->args[0]); $this->Project->interactive = false; - if (strtolower($this->args[0]) == 'all') { + if (strtolower($this->args[0]) === 'all') { return $this->all(); } @@ -152,7 +151,7 @@ class ViewTask extends BakeTask { unset($methods[$i]); } } - if ($method[0] === '_' || $method == strtolower($this->controllerName . 'Controller')) { + if ($method[0] === '_' || $method === strtolower($this->controllerName . 'Controller')) { unset($methods[$i]); } } @@ -207,10 +206,10 @@ class ViewTask extends BakeTask { $this->Controller->connection = $this->connection; $this->controllerName = $this->Controller->getName(); - $prompt = __d('cake_console', "Would you like bake to build your views interactively?\nWarning: Choosing no will overwrite %s views if it exist.", $this->controllerName); + $prompt = __d('cake_console', "Would you like bake to build your views interactively?\nWarning: Choosing no will overwrite %s views if they exist.", $this->controllerName); $interactive = $this->in($prompt, array('y', 'n'), 'n'); - if (strtolower($interactive) == 'n') { + if (strtolower($interactive) === 'n') { $this->interactive = false; } @@ -219,13 +218,13 @@ class ViewTask extends BakeTask { $wannaDoAdmin = $this->in(__d('cake_console', "Would you like to create the views for admin routing?"), array('y', 'n'), 'n'); - if (strtolower($wannaDoScaffold) == 'y' || strtolower($wannaDoAdmin) == 'y') { + if (strtolower($wannaDoScaffold) === 'y' || strtolower($wannaDoAdmin) === 'y') { $vars = $this->_loadController(); - if (strtolower($wannaDoScaffold) == 'y') { + if (strtolower($wannaDoScaffold) === 'y') { $actions = $this->scaffoldActions; $this->bakeActions($actions, $vars); } - if (strtolower($wannaDoAdmin) == 'y') { + if (strtolower($wannaDoAdmin) === 'y') { $admin = $this->Project->getPrefix(); $regularActions = $this->scaffoldActions; $adminActions = array(); @@ -249,7 +248,7 @@ class ViewTask extends BakeTask { * 'singularHumanName', 'pluralHumanName', 'fields', 'foreignKeys', * 'belongsTo', 'hasOne', 'hasMany', 'hasAndBelongsToMany' * - * @return array Returns an variables to be made available to a view template + * @return array Returns a variables to be made available to a view template */ protected function _loadController() { if (!$this->controllerName) { @@ -266,7 +265,7 @@ class ViewTask extends BakeTask { if (!class_exists($controllerClassName)) { $file = $controllerClassName . '.php'; $this->err(__d('cake_console', "The file '%s' could not be found.\nIn order to bake a view, you'll need to first create the controller.", $file)); - $this->_stop(); + return $this->_stop(); } $controllerObj = new $controllerClassName(); $controllerObj->plugin = $this->plugin; @@ -299,7 +298,7 @@ class ViewTask extends BakeTask { * Bake a view file for each of the supplied actions * * @param array $actions Array of actions to make files for. - * @param array $vars + * @param array $vars The template variables. * @return void */ public function bakeActions($actions, $vars) { @@ -316,9 +315,9 @@ class ViewTask extends BakeTask { */ public function customAction() { $action = ''; - while ($action == '') { + while (!$action) { $action = $this->in(__d('cake_console', 'Action Name? (use lowercase_underscored function name)')); - if ($action == '') { + if (!$action) { $this->out(__d('cake_console', 'The action name you supplied was empty. Please try again.')); } } @@ -331,12 +330,11 @@ class ViewTask extends BakeTask { $this->out(__d('cake_console', 'Path: %s', $this->getPath() . $this->controllerName . DS . Inflector::underscore($action) . ".ctp")); $this->hr(); $looksGood = $this->in(__d('cake_console', 'Look okay?'), array('y', 'n'), 'y'); - if (strtolower($looksGood) == 'y') { + if (strtolower($looksGood) === 'y') { $this->bake($action, ' '); - $this->_stop(); - } else { - $this->out(__d('cake_console', 'Bake Aborted.')); + return $this->_stop(); } + $this->out(__d('cake_console', 'Bake Aborted.')); } /** @@ -344,7 +342,7 @@ class ViewTask extends BakeTask { * * @param string $action Action to bake * @param string $content Content to write - * @return boolean Success + * @return bool Success */ public function bake($action, $content = '') { if ($content === true) { @@ -414,16 +412,17 @@ class ViewTask extends BakeTask { } /** - * get the option parser for this task + * Gets the option parser instance and configures it. * * @return ConsoleOptionParser */ public function getOptionParser() { $parser = parent::getOptionParser(); - return $parser->description( + + $parser->description( __d('cake_console', 'Bake views for a controller, using built-in or custom templates.') )->addArgument('controller', array( - 'help' => __d('cake_console', 'Name of the controller views to bake. Can be Plugin.name as a shortcut for plugin baking.') + 'help' => __d('cake_console', 'Name of the controller views to bake. Can be Plugin.name as a shortcut for plugin baking.') ))->addArgument('action', array( 'help' => __d('cake_console', "Will bake a single action's file. core templates are (index, add, edit, view)") ))->addArgument('alias', array( @@ -434,27 +433,37 @@ class ViewTask extends BakeTask { ))->addOption('admin', array( 'help' => __d('cake_console', 'Set to only bake views for a prefix in Routing.prefixes'), 'boolean' => true + ))->addOption('theme', array( + 'short' => 't', + 'help' => __d('cake_console', 'Theme to use when baking code.') ))->addOption('connection', array( 'short' => 'c', 'help' => __d('cake_console', 'The connection the connected model is on.') + ))->addOption('force', array( + 'short' => 'f', + 'help' => __d('cake_console', 'Force overwriting existing files without prompting.') ))->addSubcommand('all', array( 'help' => __d('cake_console', 'Bake all CRUD action views for all controllers. Requires models and controllers to exist.') - ))->epilog(__d('cake_console', 'Omitting all arguments and options will enter into an interactive mode.')); + ))->epilog( + __d('cake_console', 'Omitting all arguments and options will enter into an interactive mode.') + ); + + return $parser; } /** * Returns associations for controllers models. * - * @param Model $model - * @return array $associations + * @param Model $model The Model instance. + * @return array associations */ protected function _associations(Model $model) { $keys = array('belongsTo', 'hasOne', 'hasMany', 'hasAndBelongsToMany'); $associations = array(); - foreach ($keys as $key => $type) { + foreach ($keys as $type) { foreach ($model->{$type} as $assocKey => $assocData) { - list($plugin, $modelClass) = pluginSplit($assocData['className']); + list(, $modelClass) = pluginSplit($assocData['className']); $associations[$type][$assocKey]['primaryKey'] = $model->{$assocKey}->primaryKey; $associations[$type][$assocKey]['displayField'] = $model->{$assocKey}->displayField; $associations[$type][$assocKey]['foreignKey'] = $assocData['foreignKey']; diff --git a/lib/Cake/Console/Command/TestShell.php b/lib/Cake/Console/Command/TestShell.php index c962793..29eca27 100644 --- a/lib/Cake/Console/Command/TestShell.php +++ b/lib/Cake/Console/Command/TestShell.php @@ -4,18 +4,17 @@ * * This Shell allows the running of test suites via the cake command line * - * PHP 5 - * * CakePHP(tm) Tests - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://book.cakephp.org/2.0/en/development/testing.html * @since CakePHP(tm) v 1.2.0.4433 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ App::uses('Shell', 'Console'); @@ -39,20 +38,21 @@ class TestShell extends Shell { protected $_dispatcher = null; /** - * get the option parser for the test suite. + * Gets the option parser instance and configures it. * - * @return void + * @return ConsoleOptionParser */ public function getOptionParser() { $parser = new ConsoleOptionParser($this->name); - $parser->description(array( - __d('cake_console', 'The CakePHP Testsuite allows you to run test cases from the command line'), - ))->addArgument('category', array( + + $parser->description( + __d('cake_console', 'The CakePHP Testsuite allows you to run test cases from the command line') + )->addArgument('category', array( 'help' => __d('cake_console', 'The category for the test, or test file, to test.'), - 'required' => false, + 'required' => false ))->addArgument('file', array( 'help' => __d('cake_console', 'The path to the file, or test file, to test.'), - 'required' => false, + 'required' => false ))->addOption('log-junit', array( 'help' => __d('cake_console', ' Log test execution in JUnit XML format to file.'), 'default' => false @@ -71,6 +71,9 @@ class TestShell extends Shell { ))->addOption('coverage-clover', array( 'help' => __d('cake_console', ' Write code coverage data in Clover XML format.'), 'default' => false + ))->addOption('coverage-text', array( + 'help' => __d('cake_console', 'Output code coverage report in Text format.'), + 'boolean' => true ))->addOption('testdox-html', array( 'help' => __d('cake_console', ' Write agile documentation in HTML format to file.'), 'default' => false @@ -152,11 +155,12 @@ class TestShell extends Shell { 'default' => false ))->addOption('directive', array( 'help' => __d('cake_console', 'key[=value] Sets a php.ini value.'), + 'short' => 'd', 'default' => false ))->addOption('fixture', array( - 'help' => __d('cake_console', 'Choose a custom fixture manager.'), + 'help' => __d('cake_console', 'Choose a custom fixture manager.') ))->addOption('debug', array( - 'help' => __d('cake_console', 'More verbose output.'), + 'help' => __d('cake_console', 'More verbose output.') )); return $parser; @@ -170,20 +174,20 @@ class TestShell extends Shell { */ public function initialize() { $this->_dispatcher = new CakeTestSuiteDispatcher(); - $sucess = $this->_dispatcher->loadTestFramework(); - if (!$sucess) { - throw new Exception(__d('cake_dev', 'Please install PHPUnit framework (http://www.phpunit.de)')); + $success = $this->_dispatcher->loadTestFramework(); + if (!$success) { + throw new Exception(__d('cake_dev', 'Please install PHPUnit framework v3.7 (http://www.phpunit.de)')); } } /** * Parse the CLI options into an array CakeTestDispatcher can use. * - * @return array Array of params for CakeTestDispatcher + * @return array|null Array of params for CakeTestDispatcher or null. */ protected function _parseArgs() { if (empty($this->args)) { - return; + return null; } $params = array( 'core' => false, @@ -222,6 +226,7 @@ class TestShell extends Shell { $options = array(); $params = $this->params; unset($params['help']); + unset($params['quiet']); if (!empty($params['no-colors'])) { unset($params['no-colors'], $params['colors']); @@ -233,7 +238,11 @@ class TestShell extends Shell { if ($value === false) { continue; } - $options[] = '--' . $param; + if ($param === 'directive') { + $options[] = '-d'; + } else { + $options[] = '--' . $param; + } if (is_string($value)) { $options[] = $value; } @@ -303,7 +312,7 @@ class TestShell extends Shell { $this->out($title); $i = 1; $cases = array(); - foreach ($testCases as $testCaseFile => $testCase) { + foreach ($testCases as $testCase) { $case = str_replace('Test.php', '', $testCase); $this->out("[$i] $case"); $cases[$i] = $case; @@ -325,7 +334,7 @@ class TestShell extends Shell { break; } - if ($choice == 'q') { + if ($choice === 'q') { break; } } @@ -334,11 +343,10 @@ class TestShell extends Shell { /** * Find the test case for the passed file. The file could itself be a test. * - * @param string $file - * @param string $category - * @param boolean $throwOnMissingFile - * @access protected - * @return array(type, case) + * @param string $file The file to map. + * @param string $category The test file category. + * @param bool $throwOnMissingFile Whether or not to throw an exception. + * @return array array(type, case) * @throws Exception */ protected function _mapFileToCase($file, $category, $throwOnMissingFile = true) { @@ -412,8 +420,7 @@ class TestShell extends Shell { /** * For the given file, what category of test is it? returns app, core or the name of the plugin * - * @param string $file - * @access protected + * @param string $file The file to map. * @return string */ protected function _mapFileToCategory($file) { diff --git a/lib/Cake/Console/Command/TestsuiteShell.php b/lib/Cake/Console/Command/TestsuiteShell.php index 2f858c2..d37ac50 100644 --- a/lib/Cake/Console/Command/TestsuiteShell.php +++ b/lib/Cake/Console/Command/TestsuiteShell.php @@ -4,18 +4,17 @@ * * This is a bc wrapper for the newer Test shell * - * PHP 5 - * * CakePHP(tm) Tests - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://book.cakephp.org/2.0/en/development/testing.html * @since CakePHP(tm) v 1.2.0.4433 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ App::uses('TestShell', 'Console/Command'); @@ -33,16 +32,16 @@ App::uses('CakeTestLoader', 'TestSuite'); class TestsuiteShell extends TestShell { /** - * get the option parser for the test suite. + * Gets the option parser instance and configures it. * - * @return void + * @return ConsoleOptionParser */ public function getOptionParser() { $parser = parent::getOptionParser(); + $parser->description(array( __d('cake_console', 'The CakePHP Testsuite allows you to run test cases from the command line'), - __d('cake_console', 'This shell is for backwards-compatibility only'), - __d('cake_console', 'use the test shell instead') + __d('cake_console', "This shell is for backwards-compatibility only\nuse the test shell instead") )); return $parser; @@ -66,11 +65,11 @@ class TestsuiteShell extends TestShell { $category = $this->args[0]; - if ($category == 'core') { + if ($category === 'core') { $params['core'] = true; - } elseif ($category == 'app') { + } elseif ($category === 'app') { $params['app'] = true; - } elseif ($category != 'core') { + } elseif ($category !== 'core') { $params['plugin'] = $category; } diff --git a/lib/Cake/Console/Command/UpgradeShell.php b/lib/Cake/Console/Command/UpgradeShell.php index c9d3a21..7621c99 100644 --- a/lib/Cake/Console/Command/UpgradeShell.php +++ b/lib/Cake/Console/Command/UpgradeShell.php @@ -2,23 +2,23 @@ /** * Upgrade Shell * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package Cake.Console.Command * @since CakePHP(tm) v 2.0 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ App::uses('AppShell', 'Console/Command'); App::uses('Folder', 'Utility'); +App::uses('CakePlugin', 'Core'); /** * A shell class to help developers upgrade applications to CakePHP 2.0 @@ -103,7 +103,7 @@ class UpgradeShell extends AppShell { public function tests() { $this->_paths = array(APP . 'tests' . DS); if (!empty($this->params['plugin'])) { - $this->_paths = array(App::pluginPath($this->params['plugin']) . 'tests' . DS); + $this->_paths = array(CakePlugin::path($this->params['plugin']) . 'tests' . DS); } $patterns = array( array( @@ -129,7 +129,7 @@ class UpgradeShell extends AppShell { $cwd = getcwd(); if (!empty($this->params['plugin'])) { - chdir(App::pluginPath($this->params['plugin'])); + chdir(CakePlugin::path($this->params['plugin'])); } if (is_dir('plugins')) { @@ -200,7 +200,7 @@ class UpgradeShell extends AppShell { $dir = $options; $options = array(); } - $options = array_merge($defaultOptions, $options); + $options += $defaultOptions; $this->_movePhpFiles($dir, $options); } } @@ -216,7 +216,7 @@ class UpgradeShell extends AppShell { $this->_paths = array_diff(App::path('views'), App::core('views')); if (!empty($this->params['plugin'])) { - $this->_paths = array(App::pluginPath($this->params['plugin']) . 'views' . DS); + $this->_paths = array(CakePlugin::path($this->params['plugin']) . 'views' . DS); } $patterns = array(); @@ -230,7 +230,7 @@ class UpgradeShell extends AppShell { CakePlugin::load($plugin); $pluginHelpers = array_merge( $pluginHelpers, - App::objects('helper', App::pluginPath($plugin) . DS . 'views' . DS . 'helpers' . DS, false) + App::objects('helper', CakePlugin::path($plugin) . DS . 'views' . DS . 'helpers' . DS, false) ); } $helpers = array_merge($pluginHelpers, $helpers); @@ -261,7 +261,7 @@ class UpgradeShell extends AppShell { APP ); if (!empty($this->params['plugin'])) { - $this->_paths = array(App::pluginPath($this->params['plugin'])); + $this->_paths = array(CakePlugin::path($this->params['plugin'])); } $patterns = array( @@ -300,7 +300,7 @@ class UpgradeShell extends AppShell { APP ); if (!empty($this->params['plugin'])) { - $this->_paths = array(App::pluginPath($this->params['plugin'])); + $this->_paths = array(CakePlugin::path($this->params['plugin'])); } $patterns = array( array( @@ -355,7 +355,7 @@ class UpgradeShell extends AppShell { $this->_paths = array_merge($views, $controllers, $components); if (!empty($this->params['plugin'])) { - $pluginPath = App::pluginPath($this->params['plugin']); + $pluginPath = CakePlugin::path($this->params['plugin']); $this->_paths = array( $pluginPath . 'controllers' . DS, $pluginPath . 'controllers' . DS . 'components' . DS, @@ -393,6 +393,11 @@ class UpgradeShell extends AppShell { '/(\$this->action\b(?!\())/', '$this->request->action' ), + array( + '$this->request->onlyAllow() -> $this->request->allowMethod()', + '/\$this->request->onlyAllow\(/', + '$this->request->allowMethod(' + ) ); $this->_filesRegexpUpdate($patterns); } @@ -407,7 +412,7 @@ class UpgradeShell extends AppShell { APP ); if (!empty($this->params['plugin'])) { - $this->_paths = array(App::pluginPath($this->params['plugin'])); + $this->_paths = array(CakePlugin::path($this->params['plugin'])); } $patterns = array( array( @@ -429,7 +434,7 @@ class UpgradeShell extends AppShell { APP ); if (!empty($this->params['plugin'])) { - $this->_paths = array(App::pluginPath($this->params['plugin'])); + $this->_paths = array(CakePlugin::path($this->params['plugin'])); } $patterns = array( array( @@ -501,10 +506,33 @@ class UpgradeShell extends AppShell { $this->_filesRegexpUpdate($patterns); } +/** + * Update controller redirects. + * + * - Make redirect statements return early. + * + * @return void + */ + public function controller_redirects() { + $this->_paths = App::Path('Controller'); + if (!empty($this->params['plugin'])) { + $this->_paths = App::Path('Controller', $this->params['plugin']); + } + $patterns = array( + array( + '$this->redirect() to return $this->redirect()', + '/\t\$this-\>redirect\(/', + "\t" . 'return $this->redirect(' + ), + ); + + $this->_filesRegexpUpdate($patterns); + } + /** * Update components. * - * - Make components that extend Object to extend Component. + * - Make components that extend CakeObject to extend Component. * * @return void */ @@ -519,6 +547,11 @@ class UpgradeShell extends AppShell { '/([a-zA-Z]*Component extends) Object/', '\1 Component' ), + array( + '*Component extends CakeObject to *Component extends Component', + '/([a-zA-Z]*Component extends) CakeObject/', + '\1 Component' + ), ); $this->_filesRegexpUpdate($patterns); @@ -527,6 +560,7 @@ class UpgradeShell extends AppShell { /** * Replace cakeError with built-in exceptions. * NOTE: this ignores calls where you've passed your own secondary parameters to cakeError(). + * * @return void */ public function exceptions() { @@ -536,7 +570,7 @@ class UpgradeShell extends AppShell { $this->_paths = array_merge($controllers, $components); if (!empty($this->params['plugin'])) { - $pluginPath = App::pluginPath($this->params['plugin']); + $pluginPath = CakePlugin::path($this->params['plugin']); $this->_paths = array( $pluginPath . 'controllers' . DS, $pluginPath . 'controllers' . DS . 'components' . DS, @@ -582,7 +616,7 @@ class UpgradeShell extends AppShell { $new = 'View' . DS . Inflector::camelize($old); $old = 'View' . DS . $old; - if ($new == $old) { + if ($new === $old) { continue; } @@ -631,10 +665,10 @@ class UpgradeShell extends AppShell { /** * Move application php files to where they now should be * - * Find all php files in the folder (honoring recursive) and determine where cake expects the file to be - * If the file is not exactly where cake expects it - move it. + * Find all php files in the folder (honoring recursive) and determine where CakePHP expects the file to be + * If the file is not exactly where CakePHP expects it - move it. * - * @param string $path + * @param string $path The path to move files in. * @param array $options array(recursive, checkFolder) * @return void */ @@ -736,7 +770,7 @@ class UpgradeShell extends AppShell { /** * Searches the paths and finds files based on extension. * - * @param string $extensions + * @param string $extensions The extensions to include. Defaults to none. * @return void */ protected function _findFiles($extensions = '') { @@ -780,11 +814,13 @@ class UpgradeShell extends AppShell { } /** - * get the option parser + * Gets the option parser instance and configures it. * * @return ConsoleOptionParser */ public function getOptionParser() { + $parser = parent::getOptionParser(); + $subcommandParser = array( 'options' => array( 'plugin' => array( @@ -809,53 +845,49 @@ class UpgradeShell extends AppShell { ) ); - return parent::getOptionParser() - ->description(__d('cake_console', "A shell to help automate upgrading from CakePHP 1.3 to 2.0. \n" . - "Be sure to have a backup of your application before running these commands.")) - ->addSubcommand('all', array( - 'help' => __d('cake_console', 'Run all upgrade commands.'), - 'parser' => $subcommandParser - )) - ->addSubcommand('tests', array( - 'help' => __d('cake_console', 'Update tests class names to FooTest rather than FooTestCase.'), - 'parser' => $subcommandParser - )) - ->addSubcommand('locations', array( - 'help' => __d('cake_console', 'Move files and folders to their new homes.'), - 'parser' => $subcommandParser - )) - ->addSubcommand('i18n', array( - 'help' => __d('cake_console', 'Update the i18n translation method calls.'), - 'parser' => $subcommandParser - )) - ->addSubcommand('helpers', array( - 'help' => __d('cake_console', 'Update calls to helpers.'), - 'parser' => $subcommandParser - )) - ->addSubcommand('basics', array( - 'help' => __d('cake_console', 'Update removed basics functions to PHP native functions.'), - 'parser' => $subcommandParser - )) - ->addSubcommand('request', array( - 'help' => __d('cake_console', 'Update removed request access, and replace with $this->request.'), - 'parser' => $subcommandParser - )) - ->addSubcommand('configure', array( - 'help' => __d('cake_console', "Update Configure::read() to Configure::read('debug')"), - 'parser' => $subcommandParser - )) - ->addSubcommand('constants', array( - 'help' => __d('cake_console', "Replace Obsolete constants"), - 'parser' => $subcommandParser - )) - ->addSubcommand('components', array( - 'help' => __d('cake_console', 'Update components to extend Component class.'), - 'parser' => $subcommandParser - )) - ->addSubcommand('exceptions', array( - 'help' => __d('cake_console', 'Replace use of cakeError with exceptions.'), - 'parser' => $subcommandParser - )); + $parser->description( + __d('cake_console', "A tool to help automate upgrading an application or plugin " . + "from CakePHP 1.3 to 2.0. Be sure to have a backup of your application before " . + "running these commands." + ))->addSubcommand('all', array( + 'help' => __d('cake_console', 'Run all upgrade commands.'), + 'parser' => $subcommandParser + ))->addSubcommand('tests', array( + 'help' => __d('cake_console', 'Update tests class names to FooTest rather than FooTestCase.'), + 'parser' => $subcommandParser + ))->addSubcommand('locations', array( + 'help' => __d('cake_console', 'Move files and folders to their new homes.'), + 'parser' => $subcommandParser + ))->addSubcommand('i18n', array( + 'help' => __d('cake_console', 'Update the i18n translation method calls.'), + 'parser' => $subcommandParser + ))->addSubcommand('helpers', array( + 'help' => __d('cake_console', 'Update calls to helpers.'), + 'parser' => $subcommandParser + ))->addSubcommand('basics', array( + 'help' => __d('cake_console', 'Update removed basics functions to PHP native functions.'), + 'parser' => $subcommandParser + ))->addSubcommand('request', array( + 'help' => __d('cake_console', 'Update removed request access, and replace with $this->request.'), + 'parser' => $subcommandParser + ))->addSubcommand('configure', array( + 'help' => __d('cake_console', "Update Configure::read() to Configure::read('debug')"), + 'parser' => $subcommandParser + ))->addSubcommand('constants', array( + 'help' => __d('cake_console', "Replace Obsolete constants"), + 'parser' => $subcommandParser + ))->addSubcommand('controller_redirects', array( + 'help' => __d('cake_console', 'Return early on controller redirect calls.'), + 'parser' => $subcommandParser + ))->addSubcommand('components', array( + 'help' => __d('cake_console', 'Update components to extend Component class.'), + 'parser' => $subcommandParser + ))->addSubcommand('exceptions', array( + 'help' => __d('cake_console', 'Replace use of cakeError with exceptions.'), + 'parser' => $subcommandParser + )); + + return $parser; } } diff --git a/lib/Cake/Console/ConsoleErrorHandler.php b/lib/Cake/Console/ConsoleErrorHandler.php index e7409e8..7cbb2df 100644 --- a/lib/Cake/Console/ConsoleErrorHandler.php +++ b/lib/Cake/Console/ConsoleErrorHandler.php @@ -2,19 +2,19 @@ /** * ErrorHandler for Console Shells * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @since CakePHP(tm) v 2.0 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ + App::uses('ErrorHandler', 'Error'); App::uses('ConsoleOutput', 'Console'); App::uses('CakeLog', 'Log'); @@ -40,35 +40,37 @@ class ConsoleErrorHandler { * @return ConsoleOutput */ public static function getStderr() { - if (empty(self::$stderr)) { - self::$stderr = new ConsoleOutput('php://stderr'); + if (empty(static::$stderr)) { + static::$stderr = new ConsoleOutput('php://stderr'); } - return self::$stderr; + return static::$stderr; } /** - * Handle a exception in the console environment. Prints a message to stderr. + * Handle an exception in the console environment. Prints a message to stderr. * - * @param Exception $exception The exception to handle + * @param Exception|ParserError $exception The exception to handle * @return void */ - public function handleException(Exception $exception) { - $stderr = self::getStderr(); + public function handleException($exception) { + $stderr = static::getStderr(); $stderr->write(__d('cake_console', "Error: %s\n%s", $exception->getMessage(), $exception->getTraceAsString() )); - $this->_stop($exception->getCode() ? $exception->getCode() : 1); + $code = $exception->getCode(); + $code = ($code && is_int($code)) ? $code : 1; + return $this->_stop($code); } /** * Handle errors in the console environment. Writes errors to stderr, * and logs messages if Configure::read('debug') is 0. * - * @param integer $code Error code + * @param int $code Error code * @param string $description Description of the error. * @param string $file The file the error occurred in. - * @param integer $line The line the error occurred on. + * @param int $line The line the error occurred on. * @param array $context The backtrace of the error. * @return void */ @@ -76,24 +78,25 @@ class ConsoleErrorHandler { if (error_reporting() === 0) { return; } - $stderr = self::getStderr(); + $stderr = static::getStderr(); list($name, $log) = ErrorHandler::mapErrorCode($code); $message = __d('cake_console', '%s in [%s, line %s]', $description, $file, $line); $stderr->write(__d('cake_console', "%s Error: %s\n", $name, $message)); - if (Configure::read('debug') == 0) { + if (!Configure::read('debug')) { CakeLog::write($log, $message); } if ($log === LOG_ERR) { - $this->_stop(1); + return $this->_stop(1); } } /** * Wrapper for exit(), used for testing. * - * @param $code int The exit code. + * @param int $code The exit code. + * @return void */ protected function _stop($code = 0) { exit($code); diff --git a/lib/Cake/Console/ConsoleInput.php b/lib/Cake/Console/ConsoleInput.php index eb4928b..551635b 100644 --- a/lib/Cake/Console/ConsoleInput.php +++ b/lib/Cake/Console/ConsoleInput.php @@ -2,20 +2,20 @@ /** * ConsoleInput file. * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package Cake.Console * @since CakePHP(tm) v 2.0 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ + /** * Object wrapper for interacting with stdin * @@ -30,12 +30,24 @@ class ConsoleInput { */ protected $_input; +/** + * Can this instance use readline? + * Two conditions must be met: + * 1. Readline support must be enabled. + * 2. Handle we are attached to must be stdin. + * Allows rich editing with arrow keys and history when inputting a string. + * + * @var bool + */ + protected $_canReadline; + /** * Constructor * * @param string $handle The location of the stream to use as input. */ public function __construct($handle = 'php://stdin') { + $this->_canReadline = extension_loaded('readline') && $handle === 'php://stdin' ? true : false; $this->_input = fopen($handle, 'r'); } @@ -45,7 +57,26 @@ class ConsoleInput { * @return mixed The value of the stream */ public function read() { + if ($this->_canReadline) { + $line = readline(''); + if (!empty($line)) { + readline_add_history($line); + } + return $line; + } return fgets($this->_input); } +/** + * Checks if data is available on the stream + * + * @param int $timeout An optional time to wait for data + * @return bool True for data available, false otherwise + */ + public function dataAvailable($timeout = 0) { + $readFds = array($this->_input); + $readyFds = stream_select($readFds, $writeFds, $errorFds, $timeout); + return ($readyFds > 0); + } + } diff --git a/lib/Cake/Console/ConsoleInputArgument.php b/lib/Cake/Console/ConsoleInputArgument.php index ae7911b..08dbc21 100644 --- a/lib/Cake/Console/ConsoleInputArgument.php +++ b/lib/Cake/Console/ConsoleInputArgument.php @@ -2,19 +2,19 @@ /** * ConsoleArgumentOption file * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @since CakePHP(tm) v 2.0 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ + /** * An object to represent a single argument used in the command line. * ConsoleOptionParser creates these when you use addArgument() @@ -41,7 +41,7 @@ class ConsoleInputArgument { /** * Is this option required? * - * @var boolean + * @var bool */ protected $_required; @@ -57,7 +57,7 @@ class ConsoleInputArgument { * * @param string|array $name The long name of the option, or an array with all the properties. * @param string $help The help text for this option - * @param boolean $required Whether this argument is required. Missing required args will trigger exceptions + * @param bool $required Whether this argument is required. Missing required args will trigger exceptions * @param array $choices Valid choices for this option. */ public function __construct($name, $help = '', $required = false, $choices = array()) { @@ -85,7 +85,7 @@ class ConsoleInputArgument { /** * Generate the help for this argument. * - * @param integer $width The width to make the name of the option. + * @param int $width The width to make the name of the option. * @return string */ public function help($width = 0) { @@ -123,7 +123,7 @@ class ConsoleInputArgument { /** * Check if this argument is a required argument * - * @return boolean + * @return bool */ public function isRequired() { return (bool)$this->_required; @@ -132,8 +132,8 @@ class ConsoleInputArgument { /** * Check that $value is a valid choice for this argument. * - * @param string $value - * @return boolean + * @param string $value The choice to validate. + * @return bool * @throws ConsoleException */ public function validChoice($value) { diff --git a/lib/Cake/Console/ConsoleInputOption.php b/lib/Cake/Console/ConsoleInputOption.php index a6841fa..3a4b7a1 100644 --- a/lib/Cake/Console/ConsoleInputOption.php +++ b/lib/Cake/Console/ConsoleInputOption.php @@ -2,18 +2,17 @@ /** * ConsoleInputOption file * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @since CakePHP(tm) v 2.0 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ /** @@ -47,9 +46,9 @@ class ConsoleInputOption { protected $_help; /** - * Is the option a boolean option. Boolean options do not consume a parameter. + * Is the option a boolean option. Boolean options do not consume a parameter. * - * @var boolean + * @var bool */ protected $_boolean; @@ -73,7 +72,7 @@ class ConsoleInputOption { * @param string|array $name The long name of the option, or an array with all the properties. * @param string $short The short alias for this option * @param string $help The help text for this option - * @param boolean $boolean Whether this option is a boolean option. Boolean options don't consume extra tokens + * @param bool $boolean Whether this option is a boolean option. Boolean options don't consume extra tokens * @param string $default The default value for this option. * @param array $choices Valid choices for this option. * @throws ConsoleException @@ -119,7 +118,7 @@ class ConsoleInputOption { /** * Generate the help for this this option. * - * @param integer $width The width to make the name of the option. + * @param int $width The width to make the name of the option. * @return string */ public function help($width = 0) { @@ -169,7 +168,7 @@ class ConsoleInputOption { /** * Check if this option is a boolean option * - * @return boolean + * @return bool */ public function isBoolean() { return (bool)$this->_boolean; @@ -178,8 +177,8 @@ class ConsoleInputOption { /** * Check that a value is a valid choice for this option. * - * @param string $value - * @return boolean + * @param string $value The choice to validate. + * @return bool * @throws ConsoleException */ public function validChoice($value) { diff --git a/lib/Cake/Console/ConsoleInputSubcommand.php b/lib/Cake/Console/ConsoleInputSubcommand.php index 04e4ea3..65c10db 100644 --- a/lib/Cake/Console/ConsoleInputSubcommand.php +++ b/lib/Cake/Console/ConsoleInputSubcommand.php @@ -2,18 +2,17 @@ /** * ConsoleInputSubcommand file * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @since CakePHP(tm) v 2.0 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ /** @@ -82,7 +81,7 @@ class ConsoleInputSubcommand { /** * Generate the help for this this subcommand. * - * @param integer $width The width to make the name of the subcommand. + * @param int $width The width to make the name of the subcommand. * @return string */ public function help($width = 0) { diff --git a/lib/Cake/Console/ConsoleOptionParser.php b/lib/Cake/Console/ConsoleOptionParser.php index 8d3cdee..f54c546 100644 --- a/lib/Cake/Console/ConsoleOptionParser.php +++ b/lib/Cake/Console/ConsoleOptionParser.php @@ -2,18 +2,17 @@ /** * ConsoleOptionParser file * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @since CakePHP(tm) v 2.0 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ App::uses('TaskCollection', 'Console'); @@ -27,22 +26,22 @@ App::uses('HelpFormatter', 'Console'); /** * Handles parsing the ARGV in the command line and provides support - * for GetOpt compatible option definition. Provides a builder pattern implementation + * for GetOpt compatible option definition. Provides a builder pattern implementation * for creating shell option parsers. * * ### Options * * Named arguments come in two forms, long and short. Long arguments are preceded * by two - and give a more verbose option name. i.e. `--version`. Short arguments are - * preceded by one - and are only one character long. They usually match with a long option, + * preceded by one - and are only one character long. They usually match with a long option, * and provide a more terse alternative. * * ### Using Options * - * Options can be defined with both long and short forms. By using `$parser->addOption()` - * you can define new options. The name of the option is used as its long form, and you + * Options can be defined with both long and short forms. By using `$parser->addOption()` + * you can define new options. The name of the option is used as its long form, and you * can supply an additional short form, with the `short` option. Short options should - * only be one letter long. Using more than one letter for a short option will raise an exception. + * only be one letter long. Using more than one letter for a short option will raise an exception. * * Calling options can be done using syntax similar to most *nix command line tools. Long options * cane either include an `=` or leave it out. @@ -53,8 +52,8 @@ App::uses('HelpFormatter', 'Console'); * * `cake myshell command -cn` * - * Short options can be combined into groups as seen above. Each letter in a group - * will be treated as a separate option. The previous example is equivalent to: + * Short options can be combined into groups as seen above. Each letter in a group + * will be treated as a separate option. The previous example is equivalent to: * * `cake myshell command -c -n` * @@ -64,8 +63,8 @@ App::uses('HelpFormatter', 'Console'); * * ### Positional arguments * - * If no positional arguments are defined, all of them will be parsed. If you define positional - * arguments any arguments greater than those defined will cause exceptions. Additionally you can + * If no positional arguments are defined, all of them will be parsed. If you define positional + * arguments any arguments greater than those defined will cause exceptions. Additionally you can * declare arguments as optional, by setting the required param to false. * * `$parser->addArgument('model', array('required' => false));` @@ -73,7 +72,7 @@ App::uses('HelpFormatter', 'Console'); * ### Providing Help text * * By providing help text for your positional arguments and named arguments, the ConsoleOptionParser - * can generate a help display for you. You can view the help for shells by using the `--help` or `-h` switch. + * can generate a help display for you. You can view the help for shells by using the `--help` or `-h` switch. * * @package Cake.Console */ @@ -136,8 +135,8 @@ class ConsoleOptionParser { /** * Construct an OptionParser so you can define its behavior * - * @param string $command The command name this parser is for. The command name is used for generating help. - * @param boolean $defaultOptions Whether you want the verbose and quiet options set. Setting + * @param string $command The command name this parser is for. The command name is used for generating help. + * @param bool $defaultOptions Whether you want the verbose and quiet options set. Setting * this to false will prevent the addition of `--verbose` & `--quiet` options. */ public function __construct($command = null, $defaultOptions = true) { @@ -165,8 +164,8 @@ class ConsoleOptionParser { /** * Static factory method for creating new OptionParsers so you can chain methods off of them. * - * @param string $command The command name this parser is for. The command name is used for generating help. - * @param boolean $defaultOptions Whether you want the verbose and quiet options set. + * @param string $command The command name this parser is for. The command name is used for generating help. + * @param bool $defaultOptions Whether you want the verbose and quiet options set. * @return ConsoleOptionParser */ public static function create($command, $defaultOptions = true) { @@ -176,7 +175,7 @@ class ConsoleOptionParser { /** * Build a parser from an array. Uses an array like * - * {{{ + * ``` * $spec = array( * 'description' => 'text', * 'epilog' => 'text', @@ -190,7 +189,7 @@ class ConsoleOptionParser { * // list of subcommands to add. * ) * ); - * }}} + * ``` * * @param array $spec The spec to build the OptionParser with. * @return ConsoleOptionParser @@ -219,7 +218,7 @@ class ConsoleOptionParser { * Get or set the command name for shell/task. * * @param string $text The text to set, or null if you want to read - * @return mixed If reading, the value of the command. If setting $this will be returned + * @return string|self If reading, the value of the command. If setting $this will be returned. */ public function command($text = null) { if ($text !== null) { @@ -234,7 +233,7 @@ class ConsoleOptionParser { * * @param string|array $text The text to set, or null if you want to read. If an array the * text will be imploded with "\n" - * @return mixed If reading, the value of the description. If setting $this will be returned + * @return string|self If reading, the value of the description. If setting $this will be returned. */ public function description($text = null) { if ($text !== null) { @@ -248,11 +247,11 @@ class ConsoleOptionParser { } /** - * Get or set an epilog to the parser. The epilog is added to the end of + * Get or set an epilog to the parser. The epilog is added to the end of * the options and arguments listing when help is generated. * * @param string|array $text Text when setting or null when reading. If an array the text will be imploded with "\n" - * @return mixed If reading, the value of the epilog. If setting $this will be returned. + * @return string|self If reading, the value of the epilog. If setting $this will be returned. */ public function epilog($text = null) { if ($text !== null) { @@ -272,20 +271,20 @@ class ConsoleOptionParser { * ### Options * * - `short` - The single letter variant for this option, leave undefined for none. - * - `help` - Help text for this option. Used when generating help for the option. + * - `help` - Help text for this option. Used when generating help for the option. * - `default` - The default value for this option. Defaults are added into the parsed params when the - * attached option is not provided or has no value. Using default and boolean together will not work. + * attached option is not provided or has no value. Using default and boolean together will not work. * are added into the parsed parameters when the option is undefined. Defaults to null. * - `boolean` - The option uses no value, its just a boolean switch. Defaults to false. - * If an option is defined as boolean, it will always be added to the parsed params. If no present + * If an option is defined as boolean, it will always be added to the parsed params. If no present * it will be false, if present it will be true. - * - `choices` A list of valid choices for this option. If left empty all values are valid.. + * - `choices` A list of valid choices for this option. If left empty all values are valid.. * An exception will be raised when parse() encounters an invalid value. * * @param ConsoleInputOption|string $name The long name you want to the value to be parsed out as when options are parsed. * Will also accept an instance of ConsoleInputOption * @param array $options An array of parameters that define the behavior of the option - * @return ConsoleOptionParser $this. + * @return self */ public function addOption($name, $options = array()) { if (is_object($name) && $name instanceof ConsoleInputOption) { @@ -300,7 +299,7 @@ class ConsoleOptionParser { 'boolean' => false, 'choices' => array() ); - $options = array_merge($defaults, $options); + $options += $defaults; $option = new ConsoleInputOption($options); } $this->_options[$name] = $option; @@ -320,12 +319,12 @@ class ConsoleOptionParser { * - `index` The index for the arg, if left undefined the argument will be put * onto the end of the arguments. If you define the same index twice the first * option will be overwritten. - * - `choices` A list of valid choices for this argument. If left empty all values are valid.. + * - `choices` A list of valid choices for this argument. If left empty all values are valid.. * An exception will be raised when parse() encounters an invalid value. * - * @param ConsoleInputArgument|string $name The name of the argument. Will also accept an instance of ConsoleInputArgument + * @param ConsoleInputArgument|string $name The name of the argument. Will also accept an instance of ConsoleInputArgument * @param array $params Parameters for the argument, see above. - * @return ConsoleOptionParser $this. + * @return self */ public function addArgument($name, $params = array()) { if (is_object($name) && $name instanceof ConsoleInputArgument) { @@ -339,7 +338,7 @@ class ConsoleOptionParser { 'required' => false, 'choices' => array() ); - $options = array_merge($defaults, $params); + $options = $params + $defaults; $index = $options['index']; unset($options['index']); $arg = new ConsoleInputArgument($options); @@ -355,7 +354,7 @@ class ConsoleOptionParser { * * @param array $args Array of arguments to add. * @see ConsoleOptionParser::addArgument() - * @return ConsoleOptionParser $this + * @return self */ public function addArguments(array $args) { foreach ($args as $name => $params) { @@ -370,7 +369,7 @@ class ConsoleOptionParser { * * @param array $options Array of options to add. * @see ConsoleOptionParser::addOption() - * @return ConsoleOptionParser $this + * @return self */ public function addOptions(array $options) { foreach ($options as $name => $params) { @@ -386,13 +385,13 @@ class ConsoleOptionParser { * ### Options * * - `help` - Help text for the subcommand. - * - `parser` - A ConsoleOptionParser for the subcommand. This allows you to create method - * specific option parsers. When help is generated for a subcommand, if a parser is present + * - `parser` - A ConsoleOptionParser for the subcommand. This allows you to create method + * specific option parsers. When help is generated for a subcommand, if a parser is present * it will be used. * * @param ConsoleInputSubcommand|string $name Name of the subcommand. Will also accept an instance of ConsoleInputSubcommand * @param array $options Array of params, see above. - * @return ConsoleOptionParser $this. + * @return self */ public function addSubcommand($name, $options = array()) { if (is_object($name) && $name instanceof ConsoleInputSubcommand) { @@ -404,18 +403,29 @@ class ConsoleOptionParser { 'help' => '', 'parser' => null ); - $options = array_merge($defaults, $options); + $options += $defaults; $command = new ConsoleInputSubcommand($options); } $this->_subcommands[$name] = $command; return $this; } +/** + * Remove a subcommand from the option parser. + * + * @param string $name The subcommand name to remove. + * @return self + */ + public function removeSubcommand($name) { + unset($this->_subcommands[$name]); + return $this; + } + /** * Add multiple subcommands at once. * * @param array $commands Array of subcommands. - * @return ConsoleOptionParser $this + * @return self */ public function addSubcommands(array $commands) { foreach ($commands as $name => $params) { @@ -452,14 +462,14 @@ class ConsoleOptionParser { } /** - * Parse the argv array into a set of params and args. If $command is not null + * Parse the argv array into a set of params and args. If $command is not null * and $command is equal to a subcommand that has a parser, that parser will be used * to parse the $argv * * @param array $argv Array of args (argv) to parse. - * @param string $command The subcommand to use. If this parameter is a subcommand, that has a parser, + * @param string $command The subcommand to use. If this parameter is a subcommand, that has a parser, * That parser will be used to parse $argv instead. - * @return Array array($params, $args) + * @return array array($params, $args) * @throws ConsoleException When an invalid parameter is encountered. */ public function parse($argv, $command = null) { @@ -469,9 +479,9 @@ class ConsoleOptionParser { $params = $args = array(); $this->_tokens = $argv; while (($token = array_shift($this->_tokens)) !== null) { - if (substr($token, 0, 2) == '--') { + if (substr($token, 0, 2) === '--') { $params = $this->_parseLongOption($token, $params); - } elseif (substr($token, 0, 1) == '-') { + } elseif (substr($token, 0, 1) === '-') { $params = $this->_parseShortOption($token, $params); } else { $args = $this->_parseArg($token, $args); @@ -507,12 +517,11 @@ class ConsoleOptionParser { * @param string $subcommand If present and a valid subcommand that has a linked parser. * That subcommands help will be shown instead. * @param string $format Define the output format, can be text or xml - * @param integer $width The width to format user content to. Defaults to 72 + * @param int $width The width to format user content to. Defaults to 72 * @return string Generated help. */ public function help($subcommand = null, $format = 'text', $width = 72) { - if ( - isset($this->_subcommands[$subcommand]) && + if (isset($this->_subcommands[$subcommand]) && $this->_subcommands[$subcommand]->parser() instanceof self ) { $subparser = $this->_subcommands[$subcommand]->parser(); @@ -520,15 +529,15 @@ class ConsoleOptionParser { return $subparser->help(null, $format, $width); } $formatter = new HelpFormatter($this); - if ($format == 'text' || $format === true) { + if ($format === 'text' || $format === true) { return $formatter->text($width); - } elseif ($format == 'xml') { + } elseif ($format === 'xml') { return $formatter->xml(); } } /** - * Parse the value for a long option out of $this->_tokens. Will handle + * Parse the value for a long option out of $this->_tokens. Will handle * options with an `=` in them. * * @param string $option The option to parse. @@ -598,13 +607,14 @@ class ConsoleOptionParser { $params[$name] = $value; return $params; } + return array(); } /** * Check to see if $name has an option (short/long) defined for it. * * @param string $name The name of the option. - * @return boolean + * @return bool */ protected function _optionExists($name) { if (substr($name, 0, 2) === '--') { diff --git a/lib/Cake/Console/ConsoleOutput.php b/lib/Cake/Console/ConsoleOutput.php index 04ceb9a..ec6fb39 100644 --- a/lib/Cake/Console/ConsoleOutput.php +++ b/lib/Cake/Console/ConsoleOutput.php @@ -2,19 +2,19 @@ /** * ConsoleOutput file. * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @since CakePHP(tm) v 2.0 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ + /** * Object wrapper for outputting information from a shell application. * Can be connected to any stream resource that can be used with fopen() @@ -37,29 +37,38 @@ * `$this->out('Overwrite: foo.php was overwritten.');` * * This would create orange 'Overwrite:' text, while the rest of the text would remain the normal color. - * See ConsoleOutput::styles() to learn more about defining your own styles. Nested styles are not supported + * See ConsoleOutput::styles() to learn more about defining your own styles. Nested styles are not supported * at this time. * * @package Cake.Console */ class ConsoleOutput { + /** * Raw output constant - no modification of output text. + * + * @var int */ const RAW = 0; /** * Plain output - tags will be stripped. + * + * @var int */ const PLAIN = 1; /** * Color output - Convert known tags in to ANSI color escape codes. + * + * @var int */ const COLOR = 2; /** * Constant for a newline. + * + * @var string */ const LF = PHP_EOL; @@ -70,10 +79,18 @@ class ConsoleOutput { */ protected $_output; +/** + * The number of bytes last written to the output stream + * used when overwriting the previous message. + * + * @var int + */ + protected $_lastWritten = 0; + /** * The current output type. Manipulated with ConsoleOutput::outputAs(); * - * @var integer. + * @var int */ protected $_outputAs = self::COLOR; @@ -138,21 +155,25 @@ class ConsoleOutput { 'success' => array('text' => 'green'), 'comment' => array('text' => 'blue'), 'question' => array('text' => 'magenta'), + 'notice' => array('text' => 'cyan') ); /** * Construct the output object. * - * Checks for a pretty console environment. Ansicon allows pretty consoles - * on windows, and is supported. + * Checks for a pretty console environment. Ansicon and ConEmu allows + * pretty consoles on Windows, and is supported. * * @param string $stream The identifier of the stream to write output to. */ public function __construct($stream = 'php://stdout') { $this->_output = fopen($stream, 'w'); - if (DS == '\\' && !(bool)env('ANSICON')) { - $this->_outputAs = self::PLAIN; + if ((DS === '\\' && !(bool)env('ANSICON') && env('ConEmuANSI') !== 'ON') || + $stream === 'php://output' || + (function_exists('posix_isatty') && !posix_isatty($this->_output)) + ) { + $this->_outputAs = static::PLAIN; } } @@ -160,15 +181,44 @@ class ConsoleOutput { * Outputs a single or multiple messages to stdout. If no parameters * are passed, outputs just a newline. * - * @param string|array $message A string or a an array of strings to output - * @param integer $newlines Number of newlines to append - * @return integer Returns the number of bytes returned from writing to stdout. + * @param string|array $message A string or an array of strings to output + * @param int $newlines Number of newlines to append + * @return int Returns the number of bytes returned from writing to stdout. */ public function write($message, $newlines = 1) { if (is_array($message)) { - $message = implode(self::LF, $message); + $message = implode(static::LF, $message); + } + return $this->_write($this->styleText($message . str_repeat(static::LF, $newlines))); + } + +/** + * Overwrite some already output text. + * + * Useful for building progress bars, or when you want to replace + * text already output to the screen with new text. + * + * **Warning** You cannot overwrite text that contains newlines. + * + * @param array|string $message The message to output. + * @param int $newlines Number of newlines to append. + * @param int|null $size The number of bytes to overwrite. Defaults to the + * length of the last message output. + * @return void + */ + public function overwrite($message, $newlines = 1, $size = null) { + $size = $size ?: $this->_lastWritten; + // Output backspaces. + $this->write(str_repeat("\x08", $size), 0); + $newBytes = $this->write($message, 0); + // Fill any remaining bytes with spaces. + $fill = $size - $newBytes; + if ($fill > 0) { + $this->write(str_repeat(' ', $fill), 0); + } + if ($newlines) { + $this->write("", $newlines); } - return $this->_write($this->styleText($message . str_repeat(self::LF, $newlines))); } /** @@ -178,11 +228,11 @@ class ConsoleOutput { * @return string String with color codes added. */ public function styleText($text) { - if ($this->_outputAs == self::RAW) { + if ($this->_outputAs == static::RAW) { return $text; } - if ($this->_outputAs == self::PLAIN) { - $tags = implode('|', array_keys(self::$_styles)); + if ($this->_outputAs == static::PLAIN) { + $tags = implode('|', array_keys(static::$_styles)); return preg_replace('##', '', $text); } return preg_replace_callback( @@ -193,7 +243,7 @@ class ConsoleOutput { /** * Replace tags with color codes. * - * @param array $matches. + * @param array $matches An array of matches to replace. * @return string */ protected function _replaceTags($matches) { @@ -203,16 +253,16 @@ class ConsoleOutput { } $styleInfo = array(); - if (!empty($style['text']) && isset(self::$_foregroundColors[$style['text']])) { - $styleInfo[] = self::$_foregroundColors[$style['text']]; + if (!empty($style['text']) && isset(static::$_foregroundColors[$style['text']])) { + $styleInfo[] = static::$_foregroundColors[$style['text']]; } - if (!empty($style['background']) && isset(self::$_backgroundColors[$style['background']])) { - $styleInfo[] = self::$_backgroundColors[$style['background']]; + if (!empty($style['background']) && isset(static::$_backgroundColors[$style['background']])) { + $styleInfo[] = static::$_backgroundColors[$style['background']]; } unset($style['text'], $style['background']); foreach ($style as $option => $value) { if ($value) { - $styleInfo[] = self::$_options[$option]; + $styleInfo[] = static::$_options[$option]; } } return "\033[" . implode($styleInfo, ';') . 'm' . $matches['text'] . "\033[0m"; @@ -222,10 +272,11 @@ class ConsoleOutput { * Writes a message to the output stream. * * @param string $message Message to write. - * @return boolean success + * @return bool success */ protected function _write($message) { - return fwrite($this->_output, $message); + $this->_lastWritten = fwrite($this->_output, $message); + return $this->_lastWritten; } /** @@ -255,23 +306,23 @@ class ConsoleOutput { */ public function styles($style = null, $definition = null) { if ($style === null && $definition === null) { - return self::$_styles; + return static::$_styles; } if (is_string($style) && $definition === null) { - return isset(self::$_styles[$style]) ? self::$_styles[$style] : null; + return isset(static::$_styles[$style]) ? static::$_styles[$style] : null; } if ($definition === false) { - unset(self::$_styles[$style]); + unset(static::$_styles[$style]); return true; } - self::$_styles[$style] = $definition; + static::$_styles[$style] = $definition; return true; } /** - * Get/Set the output type to use. The output type how formatting tags are treated. + * Get/Set the output type to use. The output type how formatting tags are treated. * - * @param integer $type The output type to use. Should be one of the class constants. + * @param int $type The output type to use. Should be one of the class constants. * @return mixed Either null or the value if getting. */ public function outputAs($type = null) { @@ -282,11 +333,12 @@ class ConsoleOutput { } /** - * clean up and close handles - * + * Clean up and close handles */ public function __destruct() { - fclose($this->_output); + if (is_resource($this->_output)) { + fclose($this->_output); + } } } diff --git a/lib/Cake/Console/HelpFormatter.php b/lib/Cake/Console/HelpFormatter.php index 2b495b9..3a8fac9 100644 --- a/lib/Cake/Console/HelpFormatter.php +++ b/lib/Cake/Console/HelpFormatter.php @@ -2,26 +2,26 @@ /** * HelpFormatter * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ -App::uses('String', 'Utility'); + +App::uses('CakeText', 'Utility'); /** - * HelpFormatter formats help for console shells. Can format to either - * text or XML formats. Uses ConsoleOptionParser methods to generate help. + * HelpFormatter formats help for console shells. Can format to either + * text or XML formats. Uses ConsoleOptionParser methods to generate help. * * Generally not directly used. Using $parser->help($command, 'xml'); is usually - * how you would access help. Or via the `--help=xml` option on the command line. + * how you would access help. Or via the `--help=xml` option on the command line. * * Xml output is useful for integration with other tools like IDE's or other build tools. * @@ -33,19 +33,19 @@ class HelpFormatter { /** * The maximum number of arguments shown when generating usage. * - * @var integer + * @var int */ protected $_maxArgs = 6; /** * The maximum number of options shown when generating usage. * - * @var integer + * @var int */ protected $_maxOptions = 6; /** - * Build the help formatter for a an OptionParser + * Build the help formatter for an OptionParser * * @param ConsoleOptionParser $parser The option parser help is being generated for. */ @@ -56,7 +56,7 @@ class HelpFormatter { /** * Get the help as formatted text suitable for output on the command line. * - * @param integer $width The width of the help output. + * @param int $width The width of the help output. * @return string */ public function text($width = 72) { @@ -64,7 +64,7 @@ class HelpFormatter { $out = array(); $description = $parser->description(); if (!empty($description)) { - $out[] = String::wrap($description, $width); + $out[] = CakeText::wrap($description, $width); $out[] = ''; } $out[] = __d('cake_console', 'Usage:'); @@ -76,7 +76,7 @@ class HelpFormatter { $out[] = ''; $max = $this->_getMaxLength($subcommands) + 2; foreach ($subcommands as $command) { - $out[] = String::wrap($command->help($max), array( + $out[] = CakeText::wrap($command->help($max), array( 'width' => $width, 'indent' => str_repeat(' ', $max), 'indentAt' => 1 @@ -93,7 +93,7 @@ class HelpFormatter { $out[] = __d('cake_console', 'Options:'); $out[] = ''; foreach ($options as $option) { - $out[] = String::wrap($option->help($max), array( + $out[] = CakeText::wrap($option->help($max), array( 'width' => $width, 'indent' => str_repeat(' ', $max), 'indentAt' => 1 @@ -108,7 +108,7 @@ class HelpFormatter { $out[] = __d('cake_console', 'Arguments:'); $out[] = ''; foreach ($arguments as $argument) { - $out[] = String::wrap($argument->help($max), array( + $out[] = CakeText::wrap($argument->help($max), array( 'width' => $width, 'indent' => str_repeat(' ', $max), 'indentAt' => 1 @@ -118,7 +118,7 @@ class HelpFormatter { } $epilog = $parser->epilog(); if (!empty($epilog)) { - $out[] = String::wrap($epilog, $width); + $out[] = CakeText::wrap($epilog, $width); $out[] = ''; } return implode("\n", $out); @@ -159,8 +159,8 @@ class HelpFormatter { /** * Iterate over a collection and find the longest named thing. * - * @param array $collection - * @return integer + * @param array $collection The collection to find a max length of. + * @return int */ protected function _getMaxLength($collection) { $max = 0; @@ -173,8 +173,8 @@ class HelpFormatter { /** * Get the help as an xml string. * - * @param boolean $string Return the SimpleXml object or a string. Defaults to true. - * @return mixed. See $string + * @param bool $string Return the SimpleXml object or a string. Defaults to true. + * @return string|SimpleXmlElement See $string */ public function xml($string = true) { $parser = $this->_parser; diff --git a/lib/Cake/Console/Helper/BaseShellHelper.php b/lib/Cake/Console/Helper/BaseShellHelper.php new file mode 100644 index 0000000..f06a17a --- /dev/null +++ b/lib/Cake/Console/Helper/BaseShellHelper.php @@ -0,0 +1,82 @@ +_consoleOutput = $consoleOutput; + $this->config($config); + } + +/** + * Initialize config & store config values + * + * @param null $config Config values to set + * @return array|void + */ + public function config($config = null) { + if ($config === null) { + return $this->_config; + } + if (!$this->_configInitialized) { + $this->_config = array_merge($this->_defaultConfig, $config); + $this->_configInitialized = true; + } else { + $this->_config = array_merge($this->_config, $config); + } + } + +/** + * This method should output content using `$this->_consoleOutput`. + * + * @param array $args The arguments for the helper. + * @return void + */ + abstract public function output($args); +} \ No newline at end of file diff --git a/lib/Cake/Console/Helper/ProgressShellHelper.php b/lib/Cake/Console/Helper/ProgressShellHelper.php new file mode 100644 index 0000000..03b2169 --- /dev/null +++ b/lib/Cake/Console/Helper/ProgressShellHelper.php @@ -0,0 +1,122 @@ + null); + if (isset($args[0])) { + $args['callback'] = $args[0]; + } + if (!$args['callback'] || !is_callable($args['callback'])) { + throw new RuntimeException('Callback option must be a callable.'); + } + $this->init($args); + $callback = $args['callback']; + while ($this->_progress < $this->_total) { + $callback($this); + $this->draw(); + } + $this->_consoleOutput->write(''); + } + +/** + * Initialize the progress bar for use. + * + * - `total` The total number of items in the progress bar. Defaults + * to 100. + * - `width` The width of the progress bar. Defaults to 80. + * + * @param array $args The initialization data. + * @return void + */ + public function init(array $args = array()) { + $args += array('total' => 100, 'width' => 80); + $this->_progress = 0; + $this->_width = $args['width']; + $this->_total = $args['total']; + } + +/** + * Increment the progress bar. + * + * @param int $num The amount of progress to advance by. + * @return void + */ + public function increment($num = 1) { + $this->_progress = min(max(0, $this->_progress + $num), $this->_total); + } + +/** + * Render the progress bar based on the current state. + * + * @return void + */ + public function draw() { + $numberLen = strlen(' 100%'); + $complete = round($this->_progress / $this->_total, 2); + $barLen = ($this->_width - $numberLen) * ($this->_progress / $this->_total); + $bar = ''; + if ($barLen > 1) { + $bar = str_repeat('=', $barLen - 1) . '>'; + } + $pad = ceil($this->_width - $numberLen - $barLen); + if ($pad > 0) { + $bar .= str_repeat(' ', $pad); + } + $percent = ($complete * 100) . '%'; + $bar .= str_pad($percent, $numberLen, ' ', STR_PAD_LEFT); + $this->_consoleOutput->overwrite($bar, 0); + } +} \ No newline at end of file diff --git a/lib/Cake/Console/Helper/TableShellHelper.php b/lib/Cake/Console/Helper/TableShellHelper.php new file mode 100644 index 0000000..7cf6c79 --- /dev/null +++ b/lib/Cake/Console/Helper/TableShellHelper.php @@ -0,0 +1,124 @@ + true, + 'rowSeparator' => false, + 'headerStyle' => 'info', + ); + +/** + * Calculate the column widths + * + * @param array $rows The rows on which the columns width will be calculated on. + * @return array + */ + protected function _calculateWidths($rows) { + $widths = array(); + foreach ($rows as $line) { + for ($i = 0, $len = count($line); $i < $len; $i++) { + $columnLength = mb_strlen($line[$i]); + if ($columnLength > (isset($widths[$i]) ? $widths[$i] : 0)) { + $widths[$i] = $columnLength; + } + } + } + return $widths; + } + +/** + * Output a row separator. + * + * @param array $widths The widths of each column to output. + * @return void + */ + protected function _rowSeparator($widths) { + $out = ''; + foreach ($widths as $column) { + $out .= '+' . str_repeat('-', $column + 2); + } + $out .= '+'; + $this->_consoleOutput->write($out); + } + +/** + * Output a row. + * + * @param array $row The row to output. + * @param array $widths The widths of each column to output. + * @param array $options Options to be passed. + * @return void + */ + protected function _render($row, $widths, $options = array()) { + $out = ''; + foreach ($row as $i => $column) { + $pad = $widths[$i] - mb_strlen($column); + if (!empty($options['style'])) { + $column = $this->_addStyle($column, $options['style']); + } + $out .= '| ' . $column . str_repeat(' ', $pad) . ' '; + } + $out .= '|'; + $this->_consoleOutput->write($out); + } + +/** + * Output a table. + * + * @param array $rows The data to render out. + * @return void + */ + public function output($rows) { + $config = $this->config(); + $widths = $this->_calculateWidths($rows); + $this->_rowSeparator($widths); + if ($config['headers'] === true) { + $this->_render(array_shift($rows), $widths, array('style' => $config['headerStyle'])); + $this->_rowSeparator($widths); + } + foreach ($rows as $line) { + $this->_render($line, $widths); + if ($config['rowSeparator'] === true) { + $this->_rowSeparator($widths); + } + } + if ($config['rowSeparator'] !== true) { + $this->_rowSeparator($widths); + } + } + +/** + * Add style tags + * + * @param string $text The text to be surrounded + * @param string $style The style to be applied + * @return string + */ + protected function _addStyle($text, $style) { + return '<' . $style . '>' . $text . ''; + } +} \ No newline at end of file diff --git a/lib/Cake/Console/Shell.php b/lib/Cake/Console/Shell.php index c9dd434..4698587 100644 --- a/lib/Cake/Console/Shell.php +++ b/lib/Cake/Console/Shell.php @@ -2,18 +2,17 @@ /** * Base class for Shells * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @since CakePHP(tm) v 1.2.0.5012 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ App::uses('TaskCollection', 'Console'); @@ -21,6 +20,7 @@ App::uses('ConsoleOutput', 'Console'); App::uses('ConsoleInput', 'Console'); App::uses('ConsoleInputSubcommand', 'Console'); App::uses('ConsoleOptionParser', 'Console'); +App::uses('ClassRegistry', 'Utility'); App::uses('File', 'Utility'); /** @@ -28,13 +28,34 @@ App::uses('File', 'Utility'); * * @package Cake.Console */ -class Shell extends Object { +class Shell extends CakeObject { /** - * Output constants for making verbose and quiet shells. + * Default error code + * + * @var int + */ + const CODE_ERROR = 1; + +/** + * Output constant making verbose shells. + * + * @var int */ const VERBOSE = 2; + +/** + * Output constant for making normal shells. + * + * @var int + */ const NORMAL = 1; + +/** + * Output constants for making quiet shells. + * + * @var int + */ const QUIET = 0; /** @@ -47,7 +68,7 @@ class Shell extends Object { /** * If true, the script will ask for permission to perform actions. * - * @var boolean + * @var bool */ public $interactive = true; @@ -110,6 +131,13 @@ class Shell extends Object { */ public $uses = array(); +/** + * This shell's primary model class name, the first model in the $uses property + * + * @var string + */ + public $modelClass = null; + /** * Task Collection for the command, used to create Tasks. * @@ -145,6 +173,21 @@ class Shell extends Object { */ public $stdin; +/** + * The number of bytes last written to the output stream + * used when overwriting the previous message. + * + * @var int + */ + protected $_lastWritten = 0; + +/** + * Contains helpers which have been previously instantiated + * + * @var array + */ + protected $_helpers = array(); + /** * Constructs this Shell instance. * @@ -154,29 +197,21 @@ class Shell extends Object { * @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell */ public function __construct($stdout = null, $stderr = null, $stdin = null) { - if ($this->name == null) { + if (!$this->name) { $this->name = Inflector::camelize(str_replace(array('Shell', 'Task'), '', get_class($this))); } $this->Tasks = new TaskCollection($this); - $this->stdout = $stdout; - $this->stderr = $stderr; - $this->stdin = $stdin; - if ($this->stdout == null) { - $this->stdout = new ConsoleOutput('php://stdout'); - } - if ($this->stderr == null) { - $this->stderr = new ConsoleOutput('php://stderr'); - } - if ($this->stdin == null) { - $this->stdin = new ConsoleInput('php://stdin'); - } + $this->stdout = $stdout ? $stdout : new ConsoleOutput('php://stdout'); + $this->stderr = $stderr ? $stderr : new ConsoleOutput('php://stderr'); + $this->stdin = $stdin ? $stdin : new ConsoleInput('php://stdin'); + $this->_useLogger(); $parent = get_parent_class($this); if ($this->tasks !== null && $this->tasks !== false) { $this->_mergeVars(array('tasks'), $parent, true); } - if ($this->uses !== null && $this->uses !== false) { + if (!empty($this->uses)) { $this->_mergeVars(array('uses'), $parent, false); } } @@ -191,6 +226,7 @@ class Shell extends Object { */ public function initialize() { $this->_loadModels(); + $this->loadTasks(); } /** @@ -222,50 +258,80 @@ class Shell extends Object { } /** - * If $uses = true - * Loads AppModel file and constructs AppModel class - * makes $this->AppModel available to subclasses - * If public $uses is an array of models will load those models + * If $uses is an array load each of the models in the array * - * @return boolean + * @return bool */ protected function _loadModels() { - if ($this->uses === null || $this->uses === false) { - return; - } - App::uses('ClassRegistry', 'Utility'); - - if ($this->uses !== true && !empty($this->uses)) { - $uses = is_array($this->uses) ? $this->uses : array($this->uses); - - $modelClassName = $uses[0]; - if (strpos($uses[0], '.') !== false) { - list($plugin, $modelClassName) = explode('.', $uses[0]); + if (is_array($this->uses)) { + list(, $this->modelClass) = pluginSplit(current($this->uses)); + foreach ($this->uses as $modelClass) { + $this->loadModel($modelClass); } - $this->modelClass = $modelClassName; - - foreach ($uses as $modelClass) { - list($plugin, $modelClass) = pluginSplit($modelClass, true); - $this->{$modelClass} = ClassRegistry::init($plugin . $modelClass); - } - return true; } - return false; + return true; + } + +/** + * Lazy loads models using the loadModel() method if declared in $uses + * + * @param string $name The name of the model to look for. + * @return void + */ + public function __isset($name) { + if (is_array($this->uses)) { + foreach ($this->uses as $modelClass) { + list(, $class) = pluginSplit($modelClass); + if ($name === $class) { + return $this->loadModel($modelClass); + } + } + } + } + +/** + * Loads and instantiates models required by this shell. + * + * @param string $modelClass Name of model class to load + * @param mixed $id Initial ID the instanced model class should have + * @return mixed true when single model found and instance created, error returned if model not found. + * @throws MissingModelException if the model class cannot be found. + */ + public function loadModel($modelClass = null, $id = null) { + if ($modelClass === null) { + $modelClass = $this->modelClass; + } + + $this->uses = ($this->uses) ? (array)$this->uses : array(); + if (!in_array($modelClass, $this->uses)) { + $this->uses[] = $modelClass; + } + + list($plugin, $modelClass) = pluginSplit($modelClass, true); + if (!isset($this->modelClass)) { + $this->modelClass = $modelClass; + } + + $this->{$modelClass} = ClassRegistry::init(array( + 'class' => $plugin . $modelClass, 'alias' => $modelClass, 'id' => $id + )); + if (!$this->{$modelClass}) { + throw new MissingModelException($modelClass); + } + return true; } /** * Loads tasks defined in public $tasks * - * @return boolean + * @return bool */ public function loadTasks() { if ($this->tasks === true || empty($this->tasks) || empty($this->Tasks)) { return true; } $this->_taskMap = TaskCollection::normalizeObjectArray((array)$this->tasks); - foreach ($this->_taskMap as $task => $properties) { - $this->taskNames[] = $task; - } + $this->taskNames = array_merge($this->taskNames, array_keys($this->_taskMap)); return true; } @@ -273,7 +339,7 @@ class Shell extends Object { * Check to see if this shell has a task with the provided name. * * @param string $task The task name to check. - * @return boolean Success + * @return bool Success * @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell::hasTask */ public function hasTask($task) { @@ -284,7 +350,7 @@ class Shell extends Object { * Check to see if this shell has a callable method by the given name. * * @param string $name The method name to check. - * @return boolean + * @return bool * @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell::hasMethod */ public function hasMethod($name) { @@ -293,7 +359,7 @@ class Shell extends Object { if (!$method->isPublic() || substr($name, 0, 1) === '_') { return false; } - if ($method->getDeclaringClass()->name == 'Shell') { + if ($method->getDeclaringClass()->name === 'Shell') { return false; } return true; @@ -303,7 +369,7 @@ class Shell extends Object { } /** - * Dispatch a command to another Shell. Similar to Object::requestAction() + * Dispatch a command to another Shell. Similar to CakeObject::requestAction() * but intended for running shells from other shells. * * ### Usage: @@ -325,7 +391,7 @@ class Shell extends Object { */ public function dispatchShell() { $args = func_get_args(); - if (is_string($args[0]) && count($args) == 1) { + if (is_string($args[0]) && count($args) === 1) { $args = explode(' ', $args[0]); } @@ -401,12 +467,12 @@ class Shell extends Object { /** * Display the help in the correct format * - * @param string $command + * @param string $command The command to get help for. * @return void */ protected function _displayHelp($command) { $format = 'text'; - if (!empty($this->args[0]) && $this->args[0] == 'xml') { + if (!empty($this->args[0]) && $this->args[0] === 'xml') { $format = 'xml'; $this->stdout->outputAs(ConsoleOutput::RAW); } else { @@ -417,6 +483,7 @@ class Shell extends Object { /** * Gets the option parser instance and configures it. + * * By overriding this method you can configure the ConsoleOptionParser before returning it. * * @return ConsoleOptionParser @@ -431,7 +498,7 @@ class Shell extends Object { /** * Overload get for lazy building of tasks * - * @param string $name + * @param string $name The property name to access. * @return Shell Object of Task */ public function __get($name) { @@ -446,6 +513,19 @@ class Shell extends Object { return $this->{$name}; } +/** + * Safely access the values in $this->params. + * + * @param string $name The name of the parameter to get. + * @return string|bool|null Value. Will return null if it doesn't exist. + */ + public function param($name) { + if (!isset($this->params[$name])) { + return null; + } + return $this->params[$name]; + } + /** * Prompts the user for input, and returns it. * @@ -507,7 +587,8 @@ class Shell extends Object { $result = $this->stdin->read(); if ($result === false) { - $this->_stop(1); + $this->_stop(self::CODE_ERROR); + return self::CODE_ERROR; } $result = trim($result); @@ -523,18 +604,18 @@ class Shell extends Object { * * ### Options * - * - `width` The width to wrap to. Defaults to 72 + * - `width` The width to wrap to. Defaults to 72 * - `wordWrap` Only wrap on words breaks (spaces) Defaults to true. * - `indent` Indent the text with the string provided. Defaults to null. * * @param string $text Text the text to format. - * @param string|integer|array $options Array of options to use, or an integer to wrap the text to. + * @param string|int|array $options Array of options to use, or an integer to wrap the text to. * @return string Wrapped / indented text - * @see String::wrap() + * @see CakeText::wrap() * @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell::wrapText */ public function wrapText($text, $options = array()) { - return String::wrap($text, $options); + return CakeText::wrap($text, $options); } /** @@ -543,15 +624,15 @@ class Shell extends Object { * * ### Output levels * - * There are 3 built-in output level. Shell::QUIET, Shell::NORMAL, Shell::VERBOSE. + * There are 3 built-in output level. Shell::QUIET, Shell::NORMAL, Shell::VERBOSE. * The verbose and quiet output levels, map to the `verbose` and `quiet` output switches - * present in most shells. Using Shell::QUIET for a message means it will always display. + * present in most shells. Using Shell::QUIET for a message means it will always display. * While using Shell::VERBOSE means it will only display when verbose output is toggled. * - * @param string|array $message A string or a an array of strings to output - * @param integer $newlines Number of newlines to append - * @param integer $level The message's output level, see above. - * @return integer|boolean Returns the number of bytes returned from writing to stdout. + * @param string|array $message A string or an array of strings to output + * @param int $newlines Number of newlines to append + * @param int $level The message's output level, see above. + * @return int|bool Returns the number of bytes returned from writing to stdout. * @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell::out */ public function out($message = null, $newlines = 1, $level = Shell::NORMAL) { @@ -563,17 +644,49 @@ class Shell extends Object { $currentLevel = Shell::QUIET; } if ($level <= $currentLevel) { - return $this->stdout->write($message, $newlines); + $this->_lastWritten = $this->stdout->write($message, $newlines); + return $this->_lastWritten; } return true; } +/** + * Overwrite some already output text. + * + * Useful for building progress bars, or when you want to replace + * text already output to the screen with new text. + * + * **Warning** You cannot overwrite text that contains newlines. + * + * @param array|string $message The message to output. + * @param int $newlines Number of newlines to append. + * @param int $size The number of bytes to overwrite. Defaults to the length of the last message output. + * @return int|bool Returns the number of bytes returned from writing to stdout. + */ + public function overwrite($message, $newlines = 1, $size = null) { + $size = $size ? $size : $this->_lastWritten; + + // Output backspaces. + $this->out(str_repeat("\x08", $size), 0); + + $newBytes = $this->out($message, 0); + + // Fill any remaining bytes with spaces. + $fill = $size - $newBytes; + if ($fill > 0) { + $this->out(str_repeat(' ', $fill), 0); + } + if ($newlines) { + $this->out($this->nl($newlines), 0); + } + } + /** * Outputs a single or multiple error messages to stderr. If no parameters * are passed outputs just a newline. * - * @param string|array $message A string or a an array of strings to output - * @param integer $newlines Number of newlines to append + * @param string|array $message A string or an array of strings to output + * @param int $newlines Number of newlines to append * @return void * @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell::err */ @@ -584,7 +697,7 @@ class Shell extends Object { /** * Returns a single or multiple linefeeds sequences. * - * @param integer $multiplier Number of times the linefeed sequence should be repeated + * @param int $multiplier Number of times the linefeed sequence should be repeated * @return string * @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell::nl */ @@ -595,8 +708,8 @@ class Shell extends Object { /** * Outputs a series of minus characters to the standard output, acts as a visual separator. * - * @param integer $newlines Number of newlines to pre- and append - * @param integer $width Width of the line, defaults to 63 + * @param int $newlines Number of newlines to pre- and append + * @param int $width Width of the line, defaults to 63 * @return void * @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell::hr */ @@ -621,7 +734,8 @@ class Shell extends Object { if (!empty($message)) { $this->err($message); } - $this->_stop(1); + $this->_stop(self::CODE_ERROR); + return self::CODE_ERROR; } /** @@ -645,7 +759,7 @@ class Shell extends Object { * * @param string $path Where to put the file. * @param string $contents Content to put in the file. - * @return boolean Success + * @return bool Success * @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell::createFile */ public function createFile($path, $contents) { @@ -653,14 +767,15 @@ class Shell extends Object { $this->out(); - if (is_file($path) && $this->interactive === true) { + if (is_file($path) && empty($this->params['force']) && $this->interactive === true) { $this->out(__d('cake_console', 'File `%s` exists', $path)); $key = $this->in(__d('cake_console', 'Do you want to overwrite?'), array('y', 'n', 'q'), 'n'); - if (strtolower($key) == 'q') { + if (strtolower($key) === 'q') { $this->out(__d('cake_console', 'Quitting.'), 2); $this->_stop(); - } elseif (strtolower($key) != 'y') { + return true; + } elseif (strtolower($key) !== 'y') { $this->out(__d('cake_console', 'Skip `%s`', $path), 2); return false; } @@ -674,16 +789,38 @@ class Shell extends Object { $File->write($data); $this->out(__d('cake_console', 'Wrote `%s`', $path)); return true; - } else { - $this->err(__d('cake_console', 'Could not write to `%s`.', $path), 2); - return false; } + + $this->err(__d('cake_console', 'Could not write to `%s`.', $path), 2); + return false; + } + +/** + * Load given shell helper class + * + * @param string $name Name of the helper class. Supports plugin syntax. + * @return BaseShellHelper Instance of helper class + * @throws RuntimeException If invalid class name is provided + */ + public function helper($name) { + if (isset($this->_helpers[$name])) { + return $this->_helpers[$name]; + } + list($plugin, $helperClassName) = pluginSplit($name, true); + $helperClassName = Inflector::camelize($name) . "ShellHelper"; + App::uses($helperClassName, $plugin . "Console/Helper"); + if (!class_exists($helperClassName)) { + throw new RuntimeException("Class " . $helperClassName . " not found"); + } + $helper = new $helperClassName($this->stdout); + $this->_helpers[$name] = $helper; + return $helper; } /** * Action to create a Unit Test * - * @return boolean Success + * @return bool Success */ protected function _checkUnitTest() { if (class_exists('PHPUnit_Framework_TestCase')) { @@ -698,7 +835,7 @@ class Shell extends Object { $prompt = __d('cake_console', 'PHPUnit is not installed. Do you want to bake unit test files anyway?'); $unitTest = $this->in($prompt, array('y', 'n'), 'y'); - $result = strtolower($unitTest) == 'y' || strtolower($unitTest) == 'yes'; + $result = strtolower($unitTest) === 'y' || strtolower($unitTest) === 'yes'; if ($result) { $this->out(); @@ -773,8 +910,8 @@ class Shell extends Object { /** * creates the singular name for use in views. * - * @param string $name - * @return string $name + * @param string $name The plural underscored value. + * @return string name */ protected function _singularName($name) { return Inflector::variable(Inflector::singularize($name)); @@ -814,7 +951,7 @@ class Shell extends Object { * Find the correct path for a plugin. Scans $pluginPaths for the plugin you want. * * @param string $pluginName Name of the plugin you want ie. DebugKit - * @return string $path path to the correct plugin. + * @return string path path to the correct plugin. */ protected function _pluginPath($pluginName) { if (CakePlugin::loaded($pluginName)) { @@ -828,24 +965,57 @@ class Shell extends Object { * If you don't wish to see in your stdout or stderr everything that is logged * through CakeLog, call this function with first param as false * - * @param boolean $enable wheter to enable CakeLog output or not + * @param bool $enable whether to enable CakeLog output or not * @return void - **/ + */ protected function _useLogger($enable = true) { if (!$enable) { CakeLog::drop('stdout'); CakeLog::drop('stderr'); return; } + if (!$this->_loggerIsConfigured("stdout")) { + $this->_configureStdOutLogger(); + } + if (!$this->_loggerIsConfigured("stderr")) { + $this->_configureStdErrLogger(); + } + } + +/** + * Configure the stdout logger + * + * @return void + */ + protected function _configureStdOutLogger() { CakeLog::config('stdout', array( - 'engine' => 'ConsoleLog', + 'engine' => 'Console', 'types' => array('notice', 'info'), 'stream' => $this->stdout, )); + } + +/** + * Configure the stderr logger + * + * @return void + */ + protected function _configureStdErrLogger() { CakeLog::config('stderr', array( - 'engine' => 'ConsoleLog', + 'engine' => 'Console', 'types' => array('emergency', 'alert', 'critical', 'error', 'warning', 'debug'), 'stream' => $this->stderr, )); } + +/** + * Checks if the given logger is configured + * + * @param string $logger The name of the logger to check + * @return bool + */ + protected function _loggerIsConfigured($logger) { + $configured = CakeLog::configured(); + return in_array($logger, $configured); + } } diff --git a/lib/Cake/Console/ShellDispatcher.php b/lib/Cake/Console/ShellDispatcher.php index 426e734..9882dd9 100644 --- a/lib/Cake/Console/ShellDispatcher.php +++ b/lib/Cake/Console/ShellDispatcher.php @@ -2,18 +2,17 @@ /** * ShellDispatcher file * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @since CakePHP(tm) v 2.0 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ /** @@ -44,16 +43,14 @@ class ShellDispatcher { * a status code of either 0 or 1 according to the result of the dispatch. * * @param array $args the argv from PHP - * @param boolean $bootstrap Should the environment be bootstrapped. + * @param bool $bootstrap Should the environment be bootstrapped. */ public function __construct($args = array(), $bootstrap = true) { set_time_limit(0); + $this->parseParams($args); if ($bootstrap) { $this->_initConstants(); - } - $this->parseParams($args); - if ($bootstrap) { $this->_initEnvironment(); } } @@ -66,7 +63,7 @@ class ShellDispatcher { */ public static function run($argv) { $dispatcher = new ShellDispatcher($argv); - $dispatcher->_stop($dispatcher->dispatch() === false ? 1 : 0); + return $dispatcher->_stop($dispatcher->dispatch() === false ? 1 : 0); } /** @@ -82,9 +79,11 @@ class ShellDispatcher { } if (!defined('CAKE_CORE_INCLUDE_PATH')) { - define('DS', DIRECTORY_SEPARATOR); define('CAKE_CORE_INCLUDE_PATH', dirname(dirname(dirname(__FILE__)))); define('CAKEPHP_SHELL', true); + if (!defined('DS')) { + define('DS', DIRECTORY_SEPARATOR); + } if (!defined('CORE_PATH')) { define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS); } @@ -115,18 +114,33 @@ class ShellDispatcher { } /** - * Initializes the environment and loads the Cake core. + * Initializes the environment and loads the CakePHP core. * - * @return boolean Success. + * @return bool Success. */ protected function _bootstrap() { - define('ROOT', $this->params['root']); - define('APP_DIR', $this->params['app']); - define('APP', $this->params['working'] . DS); - define('WWW_ROOT', APP . $this->params['webroot'] . DS); - if (!is_dir(ROOT . DS . APP_DIR . DS . 'tmp')) { + if (!defined('ROOT')) { + define('ROOT', $this->params['root']); + } + if (!defined('APP_DIR')) { + define('APP_DIR', $this->params['app']); + } + if (!defined('APP')) { + define('APP', $this->params['working'] . DS); + } + if (!defined('WWW_ROOT')) { + if (!$this->_isAbsolutePath($this->params['webroot'])) { + $webroot = realpath(APP . $this->params['webroot']); + } else { + $webroot = $this->params['webroot']; + } + define('WWW_ROOT', $webroot . DS); + } + if (!defined('TMP') && !is_dir(APP . 'tmp')) { define('TMP', CAKE_CORE_INCLUDE_PATH . DS . 'Cake' . DS . 'Console' . DS . 'Templates' . DS . 'skel' . DS . 'tmp' . DS); } + + // $boot is used by Cake/bootstrap.php file $boot = file_exists(ROOT . DS . APP_DIR . DS . 'Config' . DS . 'bootstrap.php'); require CORE_PATH . 'Cake' . DS . 'bootstrap.php'; @@ -138,7 +152,9 @@ class ShellDispatcher { $this->setErrorHandlers(); if (!defined('FULL_BASE_URL')) { - define('FULL_BASE_URL', 'http://localhost'); + $url = Configure::read('App.fullBaseUrl'); + define('FULL_BASE_URL', $url ? $url : 'http://localhost'); + Configure::write('App.fullBaseUrl', FULL_BASE_URL); } return true; @@ -168,12 +184,15 @@ class ShellDispatcher { } set_exception_handler($exception['consoleHandler']); set_error_handler($error['consoleHandler'], Configure::read('Error.level')); + + App::uses('Debugger', 'Utility'); + Debugger::getInstance()->output('txt'); } /** * Dispatches a CLI request * - * @return boolean + * @return bool * @throws MissingShellMethodException */ public function dispatch() { @@ -197,12 +216,11 @@ class ShellDispatcher { if ($Shell instanceof Shell) { $Shell->initialize(); - $Shell->loadTasks(); return $Shell->runCommand($command, $this->args); } $methods = array_diff(get_class_methods($Shell), get_class_methods('Shell')); $added = in_array($command, $methods); - $private = $command[0] == '_' && method_exists($Shell, $command); + $private = $command[0] === '_' && method_exists($Shell, $command); if (!$private) { if ($added) { @@ -238,6 +256,11 @@ class ShellDispatcher { App::uses('AppShell', 'Console/Command'); App::uses($class, $plugin . 'Console/Command'); + if (!class_exists($class)) { + $plugin = Inflector::camelize($shell) . '.'; + App::uses($class, $plugin . 'Console/Command'); + } + if (!class_exists($class)) { throw new MissingShellException(array( 'class' => $class @@ -276,7 +299,11 @@ class ShellDispatcher { if (isset($params['working'])) { $params['working'] = trim($params['working']); } - if (!empty($params['working']) && (!isset($this->args[0]) || isset($this->args[0]) && $this->args[0]{0} !== '.')) { + + if (!empty($params['working']) && (!isset($this->args[0]) || isset($this->args[0]) && $this->args[0][0] !== '.')) { + if ($params['working'][0] === '.') { + $params['working'] = realpath($params['working']); + } if (empty($this->params['app']) && $params['working'] != $params['root']) { $params['root'] = dirname($params['working']); $params['app'] = basename($params['working']); @@ -285,34 +312,55 @@ class ShellDispatcher { } } - if ($params['app'][0] == '/' || preg_match('/([a-z])(:)/i', $params['app'], $matches)) { + if ($this->_isAbsolutePath($params['app'])) { $params['root'] = dirname($params['app']); } elseif (strpos($params['app'], '/')) { $params['root'] .= '/' . dirname($params['app']); } - + $isWindowsAppPath = $this->_isWindowsPath($params['app']); $params['app'] = basename($params['app']); $params['working'] = rtrim($params['root'], '/'); if (!$isWin || !preg_match('/^[A-Z]:$/i', $params['app'])) { $params['working'] .= '/' . $params['app']; } - if (!empty($matches[0]) || !empty($isWin)) { + if ($isWindowsAppPath || !empty($isWin)) { $params = str_replace('/', '\\', $params); } - $this->params = array_merge($this->params, $params); + $this->params = $params + $this->params; + } + +/** + * Checks whether the given path is absolute or relative. + * + * @param string $path absolute or relative path. + * @return bool + */ + protected function _isAbsolutePath($path) { + return $path[0] === '/' || $this->_isWindowsPath($path); + } + +/** + * Checks whether the given path is Window OS path. + * + * @param string $path absolute path. + * @return bool + */ + protected function _isWindowsPath($path) { + return preg_match('/([a-z])(:)/i', $path) == 1; } /** * Parses out the paths from from the argv * - * @param array $args + * @param array $args The argv to parse. * @return void */ protected function _parsePaths($args) { $parsed = array(); - $keys = array('-working', '--working', '-app', '--app', '-root', '--root'); + $keys = array('-working', '--working', '-app', '--app', '-root', '--root', '-webroot', '--webroot'); + $args = (array)$args; foreach ($keys as $key) { while (($index = array_search($key, $args)) !== false) { $keyname = str_replace('-', '', $key); @@ -335,7 +383,7 @@ class ShellDispatcher { } /** - * Shows console help. Performs an internal dispatch to the CommandList Shell + * Shows console help. Performs an internal dispatch to the CommandList Shell * * @return void */ @@ -347,7 +395,7 @@ class ShellDispatcher { /** * Stop execution of the current script * - * @param integer|string $status see http://php.net/exit for values + * @param int|string $status see http://php.net/exit for values * @return void */ protected function _stop($status = 0) { diff --git a/lib/Cake/Console/TaskCollection.php b/lib/Cake/Console/TaskCollection.php index 35f21ee..3fafddd 100644 --- a/lib/Cake/Console/TaskCollection.php +++ b/lib/Cake/Console/TaskCollection.php @@ -4,21 +4,22 @@ * and constructing task class objects. * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @since CakePHP(tm) v 2.0 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ App::uses('ObjectCollection', 'Utility'); /** - * Collection object for Tasks. Provides features + * Collection object for Tasks. Provides features * for lazily loading tasks, and firing callbacks on loaded tasks. * * @package Cake.Console @@ -42,15 +43,24 @@ class TaskCollection extends ObjectCollection { /** * Constructor * - * @param Shell $Shell + * @param Shell $Shell The shell this task collection is attached to. */ public function __construct(Shell $Shell) { $this->_Shell = $Shell; } /** - * Loads/constructs a task. Will return the instance in the collection - * if it already exists. + * Loads/constructs a task. Will return the instance in the registry if it already exists. + * + * You can alias your task as an existing task by setting the 'className' key, i.e., + * ``` + * public $tasks = array( + * 'DbConfig' => array( + * 'className' => 'Bakeplus.DbConfigure' + * ); + * ); + * ``` + * All calls to the `DbConfig` task would use `DbConfigure` found in the `Bakeplus` plugin instead. * * @param string $task Task name to load * @param array $settings Settings for the task. @@ -58,25 +68,33 @@ class TaskCollection extends ObjectCollection { * @throws MissingTaskException when the task could not be found */ public function load($task, $settings = array()) { + if (is_array($settings) && isset($settings['className'])) { + $alias = $task; + $task = $settings['className']; + } list($plugin, $name) = pluginSplit($task, true); + if (!isset($alias)) { + $alias = $name; + } - if (isset($this->_loaded[$name])) { - return $this->_loaded[$name]; + if (isset($this->_loaded[$alias])) { + return $this->_loaded[$alias]; } $taskClass = $name . 'Task'; App::uses($taskClass, $plugin . 'Console/Command/Task'); - if (!class_exists($taskClass)) { - if (!class_exists($taskClass)) { - throw new MissingTaskException(array( - 'class' => $taskClass - )); - } + + $exists = class_exists($taskClass); + if (!$exists) { + throw new MissingTaskException(array( + 'class' => $taskClass, + 'plugin' => substr($plugin, 0, -1) + )); } - $this->_loaded[$name] = new $taskClass( + $this->_loaded[$alias] = new $taskClass( $this->_Shell->stdout, $this->_Shell->stderr, $this->_Shell->stdin ); - return $this->_loaded[$name]; + return $this->_loaded[$alias]; } } diff --git a/lib/Cake/Console/Templates/default/actions/controller_actions.ctp b/lib/Cake/Console/Templates/default/actions/controller_actions.ctp index e34c382..dfc3092 100644 --- a/lib/Cake/Console/Templates/default/actions/controller_actions.ctp +++ b/lib/Cake/Console/Templates/default/actions/controller_actions.ctp @@ -2,19 +2,18 @@ /** * Bake Template for Controller action generation. * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package Cake.Console.Templates.default.actions * @since CakePHP(tm) v 1.3 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ ?> @@ -25,7 +24,7 @@ */ public function index() { $this->->recursive = 0; - $this->set('', $this->paginate()); + $this->set('', $this->Paginator->paginate()); } /** @@ -36,11 +35,11 @@ * @return void */ public function view($id = null) { - $this->->id = $id; - if (!$this->->exists()) { + if (!$this->->exists($id)) { throw new NotFoundException(__('Invalid ')); } - $this->set('', $this->->read(null, $id)); + $options = array('conditions' => array('.' . $this->->primaryKey => $id)); + $this->set('', $this->->find('first', $options)); } @@ -54,14 +53,12 @@ $this->->create(); if ($this->->save($this->request->data)) { - $this->Session->setFlash(__('The has been saved')); - $this->redirect(array('action' => 'index')); - - $this->flash(__(' saved.'), array('action' => 'index')); - + $this->Flash->success(__('The has been saved.')); + return $this->redirect(array('action' => 'index')); } else { - - $this->Session->setFlash(__('The could not be saved. Please, try again.')); + $this->Flash->error(__('The could not be saved. Please, try again.')); + + return $this->flash(__('The has been saved.'), array('action' => 'index')); } } @@ -91,25 +88,23 @@ * @return void */ public function edit($id = null) { - $this->->id = $id; - if (!$this->->exists()) { + if (!$this->->exists($id)) { throw new NotFoundException(__('Invalid ')); } - if ($this->request->is('post') || $this->request->is('put')) { + if ($this->request->is(array('post', 'put'))) { if ($this->->save($this->request->data)) { - $this->Session->setFlash(__('The has been saved')); - $this->redirect(array('action' => 'index')); - - $this->flash(__('The has been saved.'), array('action' => 'index')); - + $this->Flash->success(__('The has been saved.')); + return $this->redirect(array('action' => 'index')); } else { - - $this->Session->setFlash(__('The could not be saved. Please, try again.')); + $this->Flash->error(__('The could not be saved. Please, try again.')); + + return $this->flash(__('The has been saved.'), array('action' => 'index')); } } else { - $this->request->data = $this->->read(null, $id); + $options = array('conditions' => array('.' . $this->->primaryKey => $id)); + $this->request->data = $this->->find('first', $options); } delete method * - * @throws MethodNotAllowedException * @throws NotFoundException * @param string $id * @return void */ public function delete($id = null) { - if (!$this->request->is('post')) { - throw new MethodNotAllowedException(); - } $this->->id = $id; if (!$this->->exists()) { throw new NotFoundException(__('Invalid ')); } + $this->request->allowMethod('post', 'delete'); if ($this->->delete()) { - $this->Session->setFlash(__(' deleted')); - $this->redirect(array('action' => 'index')); - - $this->flash(__(' deleted'), array('action' => 'index')); - + $this->Flash->success(__('The has been deleted.')); + } else { + $this->Flash->error(__('The could not be deleted. Please, try again.')); } - - $this->Session->setFlash(__(' was not deleted')); + return $this->redirect(array('action' => 'index')); - $this->flash(__(' was not deleted'), array('action' => 'index')); + return $this->flash(__('The has been deleted.'), array('action' => 'index')); + } else { + return $this->flash(__('The could not be deleted. Please, try again.'), array('action' => 'index')); + } - $this->redirect(array('action' => 'index')); } diff --git a/lib/Cake/Console/Templates/default/classes/controller.ctp b/lib/Cake/Console/Templates/default/classes/controller.ctp index 6e27d0d..6beb4b4 100644 --- a/lib/Cake/Console/Templates/default/classes/controller.ctp +++ b/lib/Cake/Console/Templates/default/classes/controller.ctp @@ -4,19 +4,18 @@ * * Allows templating of Controllers generated from bake. * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package Cake.Console.Templates.default.classes * @since CakePHP(tm) v 1.3 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ echo " /** * Controller - * Controller extends App } diff --git a/lib/Cake/Console/Templates/default/classes/fixture.ctp b/lib/Cake/Console/Templates/default/classes/fixture.ctp index dda2baf..7ac2c39 100644 --- a/lib/Cake/Console/Templates/default/classes/fixture.ctp +++ b/lib/Cake/Console/Templates/default/classes/fixture.ctp @@ -4,25 +4,24 @@ * * Fixture Template used when baking fixtures with bake * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package Cake.Console.Templates.default.classes * @since CakePHP(tm) v 1.3 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ + +echo " - /** - * Fixture - * + * Fixture */ class Fixture extends CakeTestFixture { diff --git a/lib/Cake/Console/Templates/default/classes/model.ctp b/lib/Cake/Console/Templates/default/classes/model.ctp index f7895da..6c3e647 100644 --- a/lib/Cake/Console/Templates/default/classes/model.ctp +++ b/lib/Cake/Console/Templates/default/classes/model.ctp @@ -4,19 +4,18 @@ * * Used by bake to create new Model files. * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package Cake.Console.Templates.default.classes * @since CakePHP(tm) v 1.3 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ echo " extends AppModel { - + /** * Use database config * @@ -48,9 +47,9 @@ class extends AppModel { @@ -73,6 +72,16 @@ if ($displayField): ?> +/** + * Behaviors + * + * @var array + */ + public $actsAs = array(); + + - //The Associations below have been created with all possible keys, those that are not needed can be removed + // The Associations below have been created with all possible keys, those that are not needed can be removed '',\n"; $out .= "\t\t\t'offset' => '',\n"; $out .= "\t\t\t'finderQuery' => '',\n"; - $out .= "\t\t\t'deleteQuery' => '',\n"; - $out .= "\t\t\t'insertQuery' => ''\n"; $out .= "\t\t)"; if ($i + 1 < $habtmCount) { $out .= ","; diff --git a/lib/Cake/Console/Templates/default/classes/test.ctp b/lib/Cake/Console/Templates/default/classes/test.ctp index 2eb2b6c..2c8daa3 100644 --- a/lib/Cake/Console/Templates/default/classes/test.ctp +++ b/lib/Cake/Console/Templates/default/classes/test.ctp @@ -2,21 +2,20 @@ /** * Test Case bake template * - * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package Cake.Console.Templates.default.classes * @since CakePHP(tm) v 1.3 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ + echo " @@ -25,7 +24,6 @@ App::uses('', ''); /** * Test Case - * */ class Test extends ControllerTestCase { @@ -76,6 +74,7 @@ class Test extends CakeTestCase { * @return void */ public function test() { + $this->markTestIncomplete('test not implemented.'); } diff --git a/lib/Cake/Console/Templates/default/views/form.ctp b/lib/Cake/Console/Templates/default/views/form.ctp index b6fa788..4a21aab 100644 --- a/lib/Cake/Console/Templates/default/views/form.ctp +++ b/lib/Cake/Console/Templates/default/views/form.ctp @@ -1,19 +1,17 @@
@@ -23,7 +21,7 @@ Form->input('{$field}');\n"; @@ -46,7 +44,7 @@
    -
  • Form->postLink(__('Delete'), array('action' => 'delete', \$this->Form->value('{$modelClass}.{$primaryKey}')), null, __('Are you sure you want to delete # %s?', \$this->Form->value('{$modelClass}.{$primaryKey}'))); ?>"; ?>
  • +
  • Form->postLink(__('Delete'), array('action' => 'delete', \$this->Form->value('{$modelClass}.{$primaryKey}')), array('confirm' => __('Are you sure you want to delete # %s?', \$this->Form->value('{$modelClass}.{$primaryKey}')))); ?>"; ?>
  • Html->link(__('List " . $pluralHumanName . "'), array('action' => 'index')); ?>"; ?>
  • "; ?>

    + - + + + \n"; + echo "\n"; echo "\t\n"; foreach ($fields as $field) { $isKey = false; @@ -47,22 +47,22 @@ echo "\t\t\n"; echo "\t\n"; echo "\n"; ?> +
    Paginator->sort('{$field}'); ?>"; ?> "; ?>
    \n"; echo "\t\t\tHtml->link(__('View'), array('action' => 'view', \${$singularVar}['{$modelClass}']['{$primaryKey}'])); ?>\n"; - echo "\t\t\tHtml->link(__('Edit'), array('action' => 'edit', \${$singularVar}['{$modelClass}']['{$primaryKey}'])); ?>\n"; - echo "\t\t\tForm->postLink(__('Delete'), array('action' => 'delete', \${$singularVar}['{$modelClass}']['{$primaryKey}']), null, __('Are you sure you want to delete # %s?', \${$singularVar}['{$modelClass}']['{$primaryKey}'])); ?>\n"; + echo "\t\t\tHtml->link(__('Edit'), array('action' => 'edit', \${$singularVar}['{$modelClass}']['{$primaryKey}'])); ?>\n"; + echo "\t\t\tForm->postLink(__('Delete'), array('action' => 'delete', \${$singularVar}['{$modelClass}']['{$primaryKey}']), array('confirm' => __('Are you sure you want to delete # %s?', \${$singularVar}['{$modelClass}']['{$primaryKey}']))); ?>\n"; echo "\t\t

    Paginator->counter(array( - 'format' => __('Page {:page} of {:pages}, showing {:current} records out of {:count} total, starting on record {:start}, ending on {:end}') + 'format' => __('Page {:page} of {:pages}, showing {:current} records out of {:count} total, starting on record {:start}, ending on {:end}') )); ?>"; ?>

    -
    -

    "; ?>

    +

    "; ?>

    Html->link(__('Edit " . $singularHumanName ."'), array('action' => 'edit', \${$singularVar}['{$modelClass}']['{$primaryKey}'])); ?> \n"; - echo "\t\t
  • Form->postLink(__('Delete " . $singularHumanName . "'), array('action' => 'delete', \${$singularVar}['{$modelClass}']['{$primaryKey}']), null, __('Are you sure you want to delete # %s?', \${$singularVar}['{$modelClass}']['{$primaryKey}'])); ?>
  • \n"; + echo "\t\t
  • Form->postLink(__('Delete " . $singularHumanName . "'), array('action' => 'delete', \${$singularVar}['{$modelClass}']['{$primaryKey}']), array('confirm' => __('Are you sure you want to delete # %s?', \${$singularVar}['{$modelClass}']['{$primaryKey}']))); ?>
  • \n"; echo "\t\t
  • Html->link(__('List " . $pluralHumanName . "'), array('action' => 'index')); ?>
  • \n"; echo "\t\t
  • Html->link(__('New " . $singularHumanName . "'), array('action' => 'add')); ?>
  • \n"; @@ -54,7 +52,7 @@ foreach ($fields as $field) { foreach ($data as $alias => $details) { if ($details['controller'] != $this->name && !in_array($details['controller'], $done)) { echo "\t\t
  • Html->link(__('List " . Inflector::humanize($details['controller']) . "'), array('controller' => '{$details['controller']}', 'action' => 'index')); ?>
  • \n"; - echo "\t\t
  • Html->link(__('New " . Inflector::humanize(Inflector::underscore($alias)) . "'), array('controller' => '{$details['controller']}', 'action' => 'add')); ?>
  • \n"; + echo "\t\t
  • Html->link(__('New " . Inflector::humanize(Inflector::underscore($alias)) . "'), array('controller' => '{$details['controller']}', 'action' => 'add')); ?>
  • \n"; $done[] = $details['controller']; } } @@ -93,7 +91,6 @@ if (empty($associations['hasAndBelongsToMany'])) { $associations['hasAndBelongsToMany'] = array(); } $relations = array_merge($associations['hasMany'], $associations['hasAndBelongsToMany']); -$i = 0; foreach ($relations as $alias => $details): $otherSingularVar = Inflector::variable($alias); $otherPluralHumanName = Inflector::humanize($details['controller']); @@ -111,9 +108,7 @@ foreach ($relations as $alias => $details): "; ?> \n"; +echo "\t\n"; echo "\t\t\n"; foreach ($details['fields'] as $field) { echo "\t\t\t\n"; @@ -122,7 +117,7 @@ echo "\t\n"; echo "\t\t\t\tHtml->link(__('View'), array('controller' => '{$details['controller']}', 'action' => 'view', \${$otherSingularVar}['{$details['primaryKey']}'])); ?>\n"; echo "\t\t\t\tHtml->link(__('Edit'), array('controller' => '{$details['controller']}', 'action' => 'edit', \${$otherSingularVar}['{$details['primaryKey']}'])); ?>\n"; - echo "\t\t\t\tForm->postLink(__('Delete'), array('controller' => '{$details['controller']}', 'action' => 'delete', \${$otherSingularVar}['{$details['primaryKey']}']), null, __('Are you sure you want to delete # %s?', \${$otherSingularVar}['{$details['primaryKey']}'])); ?>\n"; + echo "\t\t\t\tForm->postLink(__('Delete'), array('controller' => '{$details['controller']}', 'action' => 'delete', \${$otherSingularVar}['{$details['primaryKey']}']), array('confirm' => __('Are you sure you want to delete # %s?', \${$otherSingularVar}['{$details['primaryKey']}']))); ?>\n"; echo "\t\t\t\n"; echo "\t\t\n"; @@ -136,4 +131,6 @@ echo "\t\n";
- + diff --git a/lib/Cake/Console/Templates/skel/.htaccess b/lib/Cake/Console/Templates/skel/.htaccess index fc3aac4..128e787 100644 --- a/lib/Cake/Console/Templates/skel/.htaccess +++ b/lib/Cake/Console/Templates/skel/.htaccess @@ -1,5 +1,5 @@ - RewriteEngine on - RewriteRule ^$ webroot/ [L] - RewriteRule (.*) webroot/$1 [L] + RewriteEngine on + RewriteRule ^$ webroot/ [L] + RewriteRule (.*) webroot/$1 [L] \ No newline at end of file diff --git a/lib/Cake/Console/Templates/skel/Config/Schema/db_acl.php b/lib/Cake/Console/Templates/skel/Config/Schema/db_acl.php index de35962..9a4f543 100644 --- a/lib/Cake/Console/Templates/skel/Config/Schema/db_acl.php +++ b/lib/Cake/Console/Templates/skel/Config/Schema/db_acl.php @@ -1,74 +1,80 @@ array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 10, 'key' => 'primary'), - 'parent_id' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10), - 'model' => array('type' => 'string', 'null' => true), - 'foreign_key' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10), - 'alias' => array('type' => 'string', 'null' => true), - 'lft' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10), - 'rght' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10), - 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)) - ); + 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 10, 'key' => 'primary'), + 'parent_id' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10), + 'model' => array('type' => 'string', 'null' => true), + 'foreign_key' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10), + 'alias' => array('type' => 'string', 'null' => true), + 'lft' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10), + 'rght' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10), + 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)) + ); +/** + * ARO - Access Request Object - Something that wants something + */ public $aros = array( - 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 10, 'key' => 'primary'), - 'parent_id' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10), - 'model' => array('type' => 'string', 'null' => true), - 'foreign_key' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10), - 'alias' => array('type' => 'string', 'null' => true), - 'lft' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10), - 'rght' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10), - 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)) - ); + 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 10, 'key' => 'primary'), + 'parent_id' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10), + 'model' => array('type' => 'string', 'null' => true), + 'foreign_key' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10), + 'alias' => array('type' => 'string', 'null' => true), + 'lft' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10), + 'rght' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10), + 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)) + ); +/** + * Used by the Cake::Model:Permission class. + * Checks if the given $aro has access to action $action in $aco. + */ public $aros_acos = array( - 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 10, 'key' => 'primary'), - 'aro_id' => array('type' => 'integer', 'null' => false, 'length' => 10, 'key' => 'index'), - 'aco_id' => array('type' => 'integer', 'null' => false, 'length' => 10), - '_create' => array('type' => 'string', 'null' => false, 'default' => '0', 'length' => 2), - '_read' => array('type' => 'string', 'null' => false, 'default' => '0', 'length' => 2), - '_update' => array('type' => 'string', 'null' => false, 'default' => '0', 'length' => 2), - '_delete' => array('type' => 'string', 'null' => false, 'default' => '0', 'length' => 2), - 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1), 'ARO_ACO_KEY' => array('column' => array('aro_id', 'aco_id'), 'unique' => 1)) - ); + 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 10, 'key' => 'primary'), + 'aro_id' => array('type' => 'integer', 'null' => false, 'length' => 10, 'key' => 'index'), + 'aco_id' => array('type' => 'integer', 'null' => false, 'length' => 10), + '_create' => array('type' => 'string', 'null' => false, 'default' => '0', 'length' => 2), + '_read' => array('type' => 'string', 'null' => false, 'default' => '0', 'length' => 2), + '_update' => array('type' => 'string', 'null' => false, 'default' => '0', 'length' => 2), + '_delete' => array('type' => 'string', 'null' => false, 'default' => '0', 'length' => 2), + 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1), 'ARO_ACO_KEY' => array('column' => array('aro_id', 'aco_id'), 'unique' => 1)) + ); } diff --git a/lib/Cake/Console/Templates/skel/Config/Schema/db_acl.sql b/lib/Cake/Console/Templates/skel/Config/Schema/db_acl.sql index f50f392..0bf3f76 100644 --- a/lib/Cake/Console/Templates/skel/Config/Schema/db_acl.sql +++ b/lib/Cake/Console/Templates/skel/Config/Schema/db_acl.sql @@ -1,8 +1,9 @@ # $Id$ # -# Copyright 2005-2012, Cake Software Foundation, Inc. +# Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) # # Licensed under The MIT License +# For full copyright and license information, please see the LICENSE.txt # Redistributions of files must retain the above copyright notice. # MIT License (http://www.opensource.org/licenses/mit-license.php) @@ -37,4 +38,15 @@ CREATE TABLE aros ( lft INTEGER(10) DEFAULT NULL, rght INTEGER(10) DEFAULT NULL, PRIMARY KEY (id) -); \ No newline at end of file +); + +/* this indexes will improve acl perfomance */ +CREATE INDEX idx_acos_lft_rght ON `acos` (`lft`, `rght`); + +CREATE INDEX idx_acos_alias ON `acos` (`alias`); + +CREATE INDEX idx_aros_lft_rght ON `aros` (`lft`, `rght`); + +CREATE INDEX idx_aros_alias ON `aros` (`alias`); + +CREATE INDEX idx_aco_id ON `aros_acos` (`aco_id`); diff --git a/lib/Cake/Console/Templates/skel/Config/Schema/i18n.php b/lib/Cake/Console/Templates/skel/Config/Schema/i18n.php index 1b8b087..cd598b3 100644 --- a/lib/Cake/Console/Templates/skel/Config/Schema/i18n.php +++ b/lib/Cake/Console/Templates/skel/Config/Schema/i18n.php @@ -1,46 +1,63 @@ array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 10, 'key' => 'primary'), 'locale' => array('type' => 'string', 'null' => false, 'length' => 6, 'key' => 'index'), diff --git a/lib/Cake/Console/Templates/skel/Config/Schema/i18n.sql b/lib/Cake/Console/Templates/skel/Config/Schema/i18n.sql index 239e146..66a42bd 100644 --- a/lib/Cake/Console/Templates/skel/Config/Schema/i18n.sql +++ b/lib/Cake/Console/Templates/skel/Config/Schema/i18n.sql @@ -1,8 +1,9 @@ # $Id$ # -# Copyright 2005-2012, Cake Software Foundation, Inc. +# Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) # # Licensed under The MIT License +# For full copyright and license information, please see the LICENSE.txt # Redistributions of files must retain the above copyright notice. # MIT License (http://www.opensource.org/licenses/mit-license.php) diff --git a/lib/Cake/Console/Templates/skel/Config/Schema/sessions.php b/lib/Cake/Console/Templates/skel/Config/Schema/sessions.php index d83e096..bd7b1ef 100644 --- a/lib/Cake/Console/Templates/skel/Config/Schema/sessions.php +++ b/lib/Cake/Console/Templates/skel/Config/Schema/sessions.php @@ -1,43 +1,60 @@ array('type' => 'string', 'null' => false, 'key' => 'primary'), 'data' => array('type' => 'text', 'null' => true, 'default' => null), diff --git a/lib/Cake/Console/Templates/skel/Config/Schema/sessions.sql b/lib/Cake/Console/Templates/skel/Config/Schema/sessions.sql index b8951b6..76845bd 100644 --- a/lib/Cake/Console/Templates/skel/Config/Schema/sessions.sql +++ b/lib/Cake/Console/Templates/skel/Config/Schema/sessions.sql @@ -1,10 +1,11 @@ # $Id$ # -# Copyright 2005-2012, Cake Software Foundation, Inc. +# Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) # 1785 E. Sahara Avenue, Suite 490-204 # Las Vegas, Nevada 89104 # # Licensed under The MIT License +# For full copyright and license information, please see the LICENSE.txt # Redistributions of files must retain the above copyright notice. # MIT License (http://www.opensource.org/licenses/mit-license.php) diff --git a/lib/Cake/Console/Templates/skel/Config/acl.ini.php b/lib/Cake/Console/Templates/skel/Config/acl.ini.php index 11ce65b..5f37e1c 100644 --- a/lib/Cake/Console/Templates/skel/Config/acl.ini.php +++ b/lib/Cake/Console/Templates/skel/Config/acl.ini.php @@ -2,23 +2,12 @@ ;/** ; * ACL Configuration ; * -; * -; * PHP 5 -; * -; * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) -; * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) -; * -; * Licensed under The MIT License -; * Redistributions of files must retain the above copyright notice. -; * -; * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) ; * @link http://cakephp.org CakePHP(tm) Project ; * @package app.Config ; * @since CakePHP(tm) v 0.10.0.1076 -; * @license MIT License (http://www.opensource.org/licenses/mit-license.php) ; */ -; acl.ini.php - Cake ACL Configuration +; acl.ini.php - CakePHP ACL Configuration ; --------------------------------------------------------------------- ; Use this file to specify user permissions. ; aco = access control object (something in your application) diff --git a/lib/Cake/Console/Templates/skel/Config/acl.php b/lib/Cake/Console/Templates/skel/Config/acl.php new file mode 100644 index 0000000..d008979 --- /dev/null +++ b/lib/Cake/Console/Templates/skel/Config/acl.php @@ -0,0 +1,124 @@ +Auth->authorize = array('Actions' => array('actionPath' => 'controllers/'),...) + * + * Now, when a user (i.e. jeff) authenticates successfully and requests a controller action (i.e. /invoices/delete) + * that is not allowed by default (e.g. via $this->Auth->allow('edit') in the Invoices controller) then AuthComponent + * will ask the configured ACL interface if access is granted. Under the assumptions 1. and 2. this will be + * done via a call to Acl->check() with + * + * array('User' => array('username' => 'jeff', 'group_id' => 4, ...)) + * + * as ARO and + * + * '/controllers/invoices/delete' + * + * as ACO. + * + * If the configured map looks like + * + * $config['map'] = array( + * 'User' => 'User/username', + * 'Role' => 'User/group_id', + * ); + * + * then PhpAcl will lookup if we defined a role like User/jeff. If that role is not found, PhpAcl will try to + * find a definition for Role/4. If the definition isn't found then a default role (Role/default) will be used to + * check rules for the given ACO. The search can be expanded by defining aliases in the alias configuration. + * E.g. if you want to use a more readable name than Role/4 in your definitions you can define an alias like + * + * $config['alias'] = array( + * 'Role/4' => 'Role/editor', + * ); + * + * In the roles configuration you can define roles on the lhs and inherited roles on the rhs: + * + * $config['roles'] = array( + * 'Role/admin' => null, + * 'Role/accountant' => null, + * 'Role/editor' => null, + * 'Role/manager' => 'Role/editor, Role/accountant', + * 'User/jeff' => 'Role/manager', + * ); + * + * In this example manager inherits all rules from editor and accountant. Role/admin doesn't inherit from any role. + * Lets define some rules: + * + * $config['rules'] = array( + * 'allow' => array( + * '*' => 'Role/admin', + * 'controllers/users/(dashboard|profile)' => 'Role/default', + * 'controllers/invoices/*' => 'Role/accountant', + * 'controllers/articles/*' => 'Role/editor', + * 'controllers/users/*' => 'Role/manager', + * 'controllers/invoices/delete' => 'Role/manager', + * ), + * 'deny' => array( + * 'controllers/invoices/delete' => 'Role/accountant, User/jeff', + * 'controllers/articles/(delete|publish)' => 'Role/editor', + * ), + * ); + * + * Ok, so as jeff inherits from Role/manager he's matched every rule that references User/jeff, Role/manager, + * Role/editor, Role/accountant and Role/default. However, for jeff, rules for User/jeff are more specific than + * rules for Role/manager, rules for Role/manager are more specific than rules for Role/editor and so on. + * This is important when allow and deny rules match for a role. E.g. Role/accountant is allowed + * controllers/invoices/* but at the same time controllers/invoices/delete is denied. But there is a more + * specific rule defined for Role/manager which is allowed controllers/invoices/delete. However, the most specific + * rule denies access to the delete action explicitly for User/jeff, so he'll be denied access to the resource. + * + * If we would remove the role definition for User/jeff, then jeff would be granted access as he would be resolved + * to Role/manager and Role/manager has an allow rule. + */ + +/** + * The role map defines how to resolve the user record from your application + * to the roles you defined in the roles configuration. + */ +$config['map'] = array( + 'User' => 'User/username', + 'Role' => 'User/group_id', +); + +/** + * define aliases to map your model information to + * the roles defined in your role configuration. + */ +$config['alias'] = array( + 'Role/4' => 'Role/editor', +); + +/** + * role configuration + */ +$config['roles'] = array( + 'Role/admin' => null, +); + +/** + * rule configuration + */ +$config['rules'] = array( + 'allow' => array( + '*' => 'Role/admin', + ), + 'deny' => array(), +); diff --git a/lib/Cake/Console/Templates/skel/Config/bootstrap.php b/lib/Cake/Console/Templates/skel/Config/bootstrap.php index 580f351..0cf81be 100644 --- a/lib/Cake/Console/Templates/skel/Config/bootstrap.php +++ b/lib/Cake/Console/Templates/skel/Config/bootstrap.php @@ -8,19 +8,9 @@ * You should also use this file to include any files that provide global functions/constants * that your application uses. * - * PHP 5 - * - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) - * - * Licensed under The MIT License - * Redistributions of files must retain the above copyright notice. - * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package app.Config * @since CakePHP(tm) v 0.10.8.2117 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ // Setup a 'default' cache configuration for use in the application. @@ -30,49 +20,46 @@ Cache::config('default', array('engine' => 'File')); * The settings below can be used to set additional paths to models, views and controllers. * * App::build(array( - * 'Model' => array('/path/to/models', '/next/path/to/models'), - * 'Model/Behavior' => array('/path/to/behaviors', '/next/path/to/behaviors'), - * 'Model/Datasource' => array('/path/to/datasources', '/next/path/to/datasources'), - * 'Model/Datasource/Database' => array('/path/to/databases', '/next/path/to/database'), - * 'Model/Datasource/Session' => array('/path/to/sessions', '/next/path/to/sessions'), - * 'Controller' => array('/path/to/controllers', '/next/path/to/controllers'), - * 'Controller/Component' => array('/path/to/components', '/next/path/to/components'), - * 'Controller/Component/Auth' => array('/path/to/auths', '/next/path/to/auths'), - * 'Controller/Component/Acl' => array('/path/to/acls', '/next/path/to/acls'), - * 'View' => array('/path/to/views', '/next/path/to/views'), - * 'View/Helper' => array('/path/to/helpers', '/next/path/to/helpers'), - * 'Console' => array('/path/to/consoles', '/next/path/to/consoles'), - * 'Console/Command' => array('/path/to/commands', '/next/path/to/commands'), - * 'Console/Command/Task' => array('/path/to/tasks', '/next/path/to/tasks'), - * 'Lib' => array('/path/to/libs', '/next/path/to/libs'), - * 'Locale' => array('/path/to/locales', '/next/path/to/locales'), - * 'Vendor' => array('/path/to/vendors', '/next/path/to/vendors'), - * 'Plugin' => array('/path/to/plugins', '/next/path/to/plugins'), + * 'Model' => array('/path/to/models/', '/next/path/to/models/'), + * 'Model/Behavior' => array('/path/to/behaviors/', '/next/path/to/behaviors/'), + * 'Model/Datasource' => array('/path/to/datasources/', '/next/path/to/datasources/'), + * 'Model/Datasource/Database' => array('/path/to/databases/', '/next/path/to/database/'), + * 'Model/Datasource/Session' => array('/path/to/sessions/', '/next/path/to/sessions/'), + * 'Controller' => array('/path/to/controllers/', '/next/path/to/controllers/'), + * 'Controller/Component' => array('/path/to/components/', '/next/path/to/components/'), + * 'Controller/Component/Auth' => array('/path/to/auths/', '/next/path/to/auths/'), + * 'Controller/Component/Acl' => array('/path/to/acls/', '/next/path/to/acls/'), + * 'View' => array('/path/to/views/', '/next/path/to/views/'), + * 'View/Helper' => array('/path/to/helpers/', '/next/path/to/helpers/'), + * 'Console' => array('/path/to/consoles/', '/next/path/to/consoles/'), + * 'Console/Command' => array('/path/to/commands/', '/next/path/to/commands/'), + * 'Console/Command/Task' => array('/path/to/tasks/', '/next/path/to/tasks/'), + * 'Lib' => array('/path/to/libs/', '/next/path/to/libs/'), + * 'Locale' => array('/path/to/locales/', '/next/path/to/locales/'), + * 'Vendor' => array('/path/to/vendors/', '/next/path/to/vendors/'), + * 'Plugin' => array('/path/to/plugins/', '/next/path/to/plugins/'), * )); - * */ /** - * Custom Inflector rules, can be set to correctly pluralize or singularize table, model, controller names or whatever other + * Custom Inflector rules can be set to correctly pluralize or singularize table, model, controller names or whatever other * string is passed to the inflection functions * * Inflector::rules('singular', array('rules' => array(), 'irregular' => array(), 'uninflected' => array())); * Inflector::rules('plural', array('rules' => array(), 'irregular' => array(), 'uninflected' => array())); - * */ /** * Plugins need to be loaded manually, you can either load them one by one or all of them in a single call - * Uncomment one of the lines below, as you need. make sure you read the documentation on CakePlugin to use more + * Uncomment one of the lines below, as you need. Make sure you read the documentation on CakePlugin to use more * advanced ways of loading plugins * * CakePlugin::loadAll(); // Loads all plugins at once - * CakePlugin::load('DebugKit'); //Loads a single plugin named DebugKit - * + * CakePlugin::load('DebugKit'); // Loads a single plugin named DebugKit */ /** - * You can attach event listeners to the request lifecyle as Dispatcher Filter . By Default CakePHP bundles two filters: + * You can attach event listeners to the request lifecycle as Dispatcher Filter . By default CakePHP bundles two filters: * * - AssetDispatcher filter will serve your asset files (css, images, js, etc) from your themes and plugins * - CacheDispatcher filter will read the Cache.check configure variable and try to serve cached content generated from controllers @@ -82,8 +69,8 @@ Cache::config('default', array('engine' => 'File')); * Configure::write('Dispatcher.filters', array( * 'MyCacheFilter', // will use MyCacheFilter class from the Routing/Filter package in your app. * 'MyPlugin.MyFilter', // will use MyFilter class from the Routing/Filter package in MyPlugin plugin. - * array('callbale' => $aFunction, 'on' => 'before', 'priority' => 9), // A valid PHP callback type to be called on beforeDispatch - * array('callbale' => $anotherMethod, 'on' => 'after'), // A valid PHP callback type to be called on afterDispatch + * array('callable' => $aFunction, 'on' => 'before', 'priority' => 9), // A valid PHP callback type to be called on beforeDispatch + * array('callable' => $anotherMethod, 'on' => 'after'), // A valid PHP callback type to be called on afterDispatch * * )); */ @@ -97,12 +84,12 @@ Configure::write('Dispatcher.filters', array( */ App::uses('CakeLog', 'Log'); CakeLog::config('debug', array( - 'engine' => 'FileLog', + 'engine' => 'File', 'types' => array('notice', 'info', 'debug'), 'file' => 'debug', )); CakeLog::config('error', array( - 'engine' => 'FileLog', + 'engine' => 'File', 'types' => array('warning', 'error', 'critical', 'alert', 'emergency'), 'file' => 'error', )); diff --git a/lib/Cake/Console/Templates/skel/Config/core.php b/lib/Cake/Console/Templates/skel/Config/core.php index 14ad697..18d645a 100644 --- a/lib/Cake/Console/Templates/skel/Config/core.php +++ b/lib/Cake/Console/Templates/skel/Config/core.php @@ -4,19 +4,9 @@ * * Use it to configure core behavior of Cake. * - * PHP 5 - * - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) - * - * Licensed under The MIT License - * Redistributions of files must retain the above copyright notice. - * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package app.Config * @since CakePHP(tm) v 0.2.9 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ /** @@ -35,8 +25,8 @@ Configure::write('debug', 2); /** - * Configure the Error handler used to handle errors for your application. By default - * ErrorHandler::handleError() is used. It will display errors using Debugger, when debug > 0 + * Configure the Error handler used to handle errors for your application. By default + * ErrorHandler::handleError() is used. It will display errors using Debugger, when debug > 0 * and log errors with CakeLog when debug = 0. * * Options: @@ -44,7 +34,7 @@ * - `handler` - callback - The callback to handle errors. You can set this to any callable type, * including anonymous functions. * Make sure you add App::uses('MyHandler', 'Error'); when using a custom handler class - * - `level` - int - The level of errors you are interested in capturing. + * - `level` - integer - The level of errors you are interested in capturing. * - `trace` - boolean - Include stack traces for errors in log files. * * @see ErrorHandler for more information on error handling and configuration. @@ -56,9 +46,9 @@ )); /** - * Configure the Exception handler used for uncaught exceptions. By default, + * Configure the Exception handler used for uncaught exceptions. By default, * ErrorHandler::handleException() is used. It will display a HTML page for the exception, and - * while debug > 0, framework errors like Missing Controller will be displayed. When debug = 0, + * while debug > 0, framework errors like Missing Controller will be displayed. When debug = 0, * framework errors will be coerced into generic HTTP errors. * * Options: @@ -66,9 +56,12 @@ * - `handler` - callback - The callback to handle exceptions. You can set this to any callback type, * including anonymous functions. * Make sure you add App::uses('MyHandler', 'Error'); when using a custom handler class - * - `renderer` - string - The class responsible for rendering uncaught exceptions. If you choose a custom class you + * - `renderer` - string - The class responsible for rendering uncaught exceptions. If you choose a custom class you * should place the file for that class in app/Lib/Error. This class needs to implement a render method. * - `log` - boolean - Should Exceptions be logged? + * - `skipLog` - array - list of exceptions to skip for logging. Exceptions that + * extend one of the listed exceptions will also be skipped for logging. + * Example: `'skipLog' => array('NotFoundException', 'UnauthorizedException')` * * @see ErrorHandler for more information on exception handling and configuration. */ @@ -92,10 +85,45 @@ * /app/.htaccess * /app/webroot/.htaccess * - * And uncomment the App.baseUrl below: + * And uncomment the App.baseUrl below. But keep in mind + * that plugin assets such as images, CSS and JavaScript files + * will not work without URL rewriting! + * To work around this issue you should either symlink or copy + * the plugin assets into you app's webroot directory. This is + * recommended even when you are using mod_rewrite. Handling static + * assets through the Dispatcher is incredibly inefficient and + * included primarily as a development convenience - and + * thus not recommended for production applications. */ //Configure::write('App.baseUrl', env('SCRIPT_NAME')); +/** + * To configure CakePHP to use a particular domain URL + * for any URL generation inside the application, set the following + * configuration variable to the http(s) address to your domain. This + * will override the automatic detection of full base URL and can be + * useful when generating links from the CLI (e.g. sending emails) + */ + //Configure::write('App.fullBaseUrl', 'http://example.com'); + +/** + * Web path to the public images directory under webroot. + * If not set defaults to 'img/' + */ + //Configure::write('App.imageBaseUrl', 'img/'); + +/** + * Web path to the CSS files directory under webroot. + * If not set defaults to 'css/' + */ + //Configure::write('App.cssBaseUrl', 'css/'); + +/** + * Web path to the js files directory under webroot. + * If not set defaults to 'js/' + */ + //Configure::write('App.jsBaseUrl', 'js/'); + /** * Uncomment the define below to use CakePHP prefix routes. * @@ -110,13 +138,11 @@ * Enables: * `admin_index()` and `/admin/controller/index` * `manager_index()` and `/manager/controller/index` - * */ //Configure::write('Routing.prefixes', array('admin')); /** * Turn off all caching application-wide. - * */ //Configure::write('Cache.disable', true); @@ -127,15 +153,18 @@ * public $cacheAction inside your controllers to define caching settings. * You can either set it controller-wide by setting public $cacheAction = true, * or in each action using $this->cacheAction = true. - * */ //Configure::write('Cache.check', true); /** - * Defines the default error type when using the log() function. Used for - * differentiating error logging and debugging. Currently PHP supports LOG_DEBUG. + * Enable cache view prefixes. + * + * If set it will be prepended to the cache name for view file caching. This is + * helpful if you deploy the same application via multiple subdomains and languages, + * for instance. Each version can then have its own view cache namespace. + * Note: The final cache file name will then be `prefix_cachefilename`. */ - define('LOG_ERROR', LOG_ERR); + //Configure::write('Cache.viewPrefix', 'prefix'); /** * Session configuration. @@ -153,8 +182,8 @@ * value to false, when dealing with older versions of IE, Chrome Frame or certain web-browsing devices and AJAX * - `Session.defaults` - The default configuration set to use as a basis for your session. * There are four builtins: php, cake, cache, database. - * - `Session.handler` - Can be used to enable a custom session handler. Expects an array of of callables, - * that can be used with `session_save_handler`. Using this option will automatically add `session.save_handler` + * - `Session.handler` - Can be used to enable a custom session handler. Expects an array of callables, + * that can be used with `session_save_handler`. Using this option will automatically add `session.save_handler` * to the ini array. * - `Session.autoRegenerate` - Enabling this setting, turns on automatic renewal of sessions, and * sessionids that change frequently. See CakeSession::$requestCountdown. @@ -172,17 +201,11 @@ * * To use database sessions, run the app/Config/Schema/sessions.php schema using * the cake shell command: cake schema create Sessions - * */ Configure::write('Session', array( 'defaults' => 'php' )); -/** - * The level of CakePHP security. - */ - Configure::write('Security.level', 'medium'); - /** * A random string used in security hashing methods. */ @@ -195,7 +218,7 @@ /** * Apply timestamps with the last modified time to static assets (js, css, images). - * Will append a querystring parameter containing the time the file was modified. This is + * Will append a query string parameter containing the time the file was modified. This is * useful for invalidating browser caches. * * Set to `true` to apply timestamps when debug > 0. Set to 'force' to always enable @@ -216,12 +239,12 @@ * Plug in your own custom JavaScript compressor by dropping a script in your webroot to handle the * output, and setting the config below to the name of the script. * - * To use, prefix your JavaScript link URLs with '/cjs/' instead of '/js/' or use JavaScriptHelper::link(). + * To use, prefix your JavaScript link URLs with '/cjs/' instead of '/js/' or use JsHelper::link(). */ //Configure::write('Asset.filter.js', 'custom_javascript_output_filter.php'); /** - * The classname and database used in CakePHP's + * The class name and database used in CakePHP's * access control lists. */ Configure::write('Acl.classname', 'DbAcl'); @@ -234,7 +257,6 @@ //date_default_timezone_set('UTC'); /** - * * Cache Engine Configuration * Default settings provided below * @@ -247,7 +269,8 @@ * 'path' => CACHE, //[optional] use system tmp directory - remember to use absolute path * 'prefix' => 'cake_', //[optional] prefix every cache file with this string * 'lock' => false, //[optional] use file locking - * 'serialize' => true, [optional] + * 'serialize' => true, //[optional] + * 'mask' => 0664, //[optional] * )); * * APC (http://pecl.php.net/package/APC) @@ -295,18 +318,20 @@ */ /** - * Pick the caching engine to use. If APC is enabled use it. - * If running via cli - apc is disabled by default. ensure it's available and enabled in this case + * Configure the cache handlers that CakePHP will use for internal + * metadata like class maps, and model schema. * + * By default File is used, but for improved performance you should use APC. + * + * Note: 'default' and other application caches should be configured in app/Config/bootstrap.php. + * Please check the comments in bootstrap.php for more info on the cache engines available + * and their settings. */ $engine = 'File'; -if (extension_loaded('apc') && function_exists('apc_dec') && (php_sapi_name() !== 'cli' || ini_get('apc.enable_cli'))) { - $engine = 'Apc'; -} // In development mode, caches should expire quickly. $duration = '+999 days'; -if (Configure::read('debug') >= 1) { +if (Configure::read('debug') > 0) { $duration = '+10 seconds'; } @@ -314,7 +339,7 @@ if (Configure::read('debug') >= 1) { $prefix = 'myapp_'; /** - * Configure the cache used for general framework caching. Path information, + * Configure the cache used for general framework caching. Path information, * object listings, and translation cache files are stored with this configuration. */ Cache::config('_cake_core_', array( @@ -326,7 +351,7 @@ Cache::config('_cake_core_', array( )); /** - * Configure the cache for model and datasource caches. This cache configuration + * Configure the cache for model and datasource caches. This cache configuration * is used to store schema descriptions, and table listings in connections. */ Cache::config('_cake_model_', array( diff --git a/lib/Cake/Console/Templates/skel/Config/database.php.default b/lib/Cake/Console/Templates/skel/Config/database.php.default index 245c282..cc549a5 100644 --- a/lib/Cake/Console/Templates/skel/Config/database.php.default +++ b/lib/Cake/Console/Templates/skel/Config/database.php.default @@ -1,40 +1,22 @@ The name of a supported datasource; valid options are as follows: - * Database/Mysql - MySQL 4 & 5, - * Database/Sqlite - SQLite (PHP5 only), - * Database/Postgres - PostgreSQL 7 and higher, - * Database/Sqlserver - Microsoft SQL Server 2005 and higher + * Database/Mysql - MySQL 4 & 5, + * Database/Sqlite - SQLite (PHP5 only), + * Database/Postgres - PostgreSQL 7 and higher, + * Database/Sqlserver - Microsoft SQL Server 2005 and higher * * You can add custom database datasources (or override existing datasources) by adding the - * appropriate file to app/Model/Datasource/Database. Datasources should be named 'MyDatasource.php', + * appropriate file to app/Model/Datasource/Database. Datasources should be named 'MyDatasource.php', * * * persistent => true / false @@ -44,11 +26,11 @@ * the host you connect to the database. To add a socket or port number, use 'port' => # * * prefix => - * Uses the given prefix for all the tables in this database. This setting can be overridden + * Uses the given prefix for all the tables in this database. This setting can be overridden * on a per-table basis with the Model::$tablePrefix property. * * schema => - * For Postgres/Sqlserver specifies which schema you would like to use the tables in. Postgres defaults to 'public'. For Sqlserver, it defaults to empty and use + * For Postgres/Sqlserver specifies which schema you would like to use the tables in. Postgres defaults to 'public'. For Sqlserver, it defaults to empty and use * the connected user's default schema (typically 'dbo'). * * encoding => @@ -57,6 +39,15 @@ * * unix_socket => * For MySQL to connect via socket specify the `unix_socket` parameter instead of `host` and `port` + * + * settings => + * Array of key/value pairs, on connection it executes SET statements for each pair + * For MySQL : http://dev.mysql.com/doc/refman/5.6/en/set-statement.html + * For Postgres : http://www.postgresql.org/docs/9.2/static/sql-set.html + * For Sql Server : http://msdn.microsoft.com/en-us/library/ms190356.aspx + * + * flags => + * A key/value array of driver specific connection options. */ class DATABASE_CONFIG { diff --git a/lib/Cake/Console/Templates/skel/Config/email.php.default b/lib/Cake/Console/Templates/skel/Config/email.php.default index c423f78..0a01e38 100644 --- a/lib/Cake/Console/Templates/skel/Config/email.php.default +++ b/lib/Cake/Console/Templates/skel/Config/email.php.default @@ -4,41 +4,26 @@ * * Use it to configure email transports of Cake. * - * PHP 5 - * - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) - * - * Licensed under The MIT License - * Redistributions of files must retain the above copyright notice. - * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package app.Config * @since CakePHP(tm) v 2.0.0 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) - */ -/** - * In this file you set up your send email details. - * - * @package cake.config */ + /** * Email configuration class. * You can specify multiple configurations for production, development and testing. * * transport => The name of a supported transport; valid options are as follows: - * Mail - Send using PHP mail function + * Mail - Send using PHP mail function * Smtp - Send using SMTP * Debug - Do not send the email, just return the result * * You can add custom transports (or override existing transports) by adding the - * appropriate file to app/Network/Email. Transports should be named 'YourTransport.php', + * appropriate file to app/Network/Email. Transports should be named 'YourTransport.php', * where 'Your' is the name of the transport. * * from => * The origin email. See CakeEmail::from() about the valid values - * */ class EmailConfig { @@ -58,7 +43,7 @@ class EmailConfig { 'username' => 'user', 'password' => 'secret', 'client' => null, - 'log' => false + 'log' => false, //'charset' => 'utf-8', //'headerCharset' => 'utf-8', ); diff --git a/lib/Cake/Console/Templates/skel/Config/routes.php b/lib/Cake/Console/Templates/skel/Config/routes.php index c68cc3e..2562ebe 100644 --- a/lib/Cake/Console/Templates/skel/Config/routes.php +++ b/lib/Cake/Console/Templates/skel/Config/routes.php @@ -4,22 +4,13 @@ * * In this file, you set up routes to your controllers and their actions. * Routes are very important mechanism that allows you to freely connect - * different urls to chosen controllers and their actions (functions). + * different URLs to chosen controllers and their actions (functions). * - * PHP 5 - * - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) - * - * Licensed under The MIT License - * Redistributions of files must retain the above copyright notice. - * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package app.Config * @since CakePHP(tm) v 0.2.9 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ + /** * Here, we are connecting '/' (base path) to controller called 'Pages', * its action called 'display', and we pass a param to select the view file @@ -27,12 +18,12 @@ */ Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home')); /** - * ...and connect the rest of 'Pages' controller's urls. + * ...and connect the rest of 'Pages' controller's URLs. */ Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display')); /** - * Load all plugin routes. See the CakePlugin documentation on + * Load all plugin routes. See the CakePlugin documentation on * how to customize the loading of plugin routes. */ CakePlugin::routes(); diff --git a/lib/Cake/Console/Templates/skel/Console/Command/AppShell.php b/lib/Cake/Console/Templates/skel/Console/Command/AppShell.php index 5cc915f..04a3430 100644 --- a/lib/Cake/Console/Templates/skel/Console/Command/AppShell.php +++ b/lib/Cake/Console/Templates/skel/Console/Command/AppShell.php @@ -2,18 +2,8 @@ /** * AppShell file * - * PHP 5 - * - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) - * - * Licensed under The MIT License - * Redistributions of files must retain the above copyright notice. - * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @since CakePHP(tm) v 2.0 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ App::uses('Shell', 'Console'); diff --git a/lib/Cake/Console/Templates/skel/Console/cake b/lib/Cake/Console/Templates/skel/Console/cake index 447743d..6745451 100644 --- a/lib/Cake/Console/Templates/skel/Console/cake +++ b/lib/Cake/Console/Templates/skel/Console/cake @@ -2,32 +2,40 @@ ################################################################################ # # Bake is a shell script for running CakePHP bake script -# PHP 5 # # CakePHP(tm) : Rapid Development Framework (http://cakephp.org) -# Copyright 2005-2012, Cake Software Foundation, Inc. +# Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) # # Licensed under The MIT License +# For full copyright and license information, please see the LICENSE.txt # Redistributions of files must retain the above copyright notice. # -# @copyright Copyright 2005-2012, Cake Software Foundation, Inc. -# @link http://cakephp.org CakePHP(tm) Project -# @package app.Console -# @since CakePHP(tm) v 2.0 -# @license MIT License (http://www.opensource.org/licenses/mit-license.php) +# @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) +# @link http://cakephp.org CakePHP(tm) Project +# @package app.Console +# @since CakePHP(tm) v 1.2.0.5012 +# @license http://www.opensource.org/licenses/mit-license.php MIT License # ################################################################################ -LIB=$(cd -P -- "$(dirname -- "$0")" && pwd -P) && LIB=$LIB/$(basename -- "$0") -while [ -h "$LIB" ]; do - DIR=$(dirname -- "$LIB") - SYM=$(readlink "$LIB") - LIB=$(cd "$DIR" && cd $(dirname -- "$SYM") && pwd)/$(basename -- "$SYM") -done +# Canonicalize by following every symlink of the given name recursively +canonicalize() { + NAME="$1" + if [ -f "$NAME" ] + then + DIR=$(dirname -- "$NAME") + NAME=$(cd -P "$DIR" && pwd -P)/$(basename -- "$NAME") + fi + while [ -h "$NAME" ]; do + DIR=$(dirname -- "$NAME") + SYM=$(readlink "$NAME") + NAME=$(cd "$DIR" && cd $(dirname -- "$SYM") && pwd)/$(basename -- "$SYM") + done + echo "$NAME" +} -LIB=$(dirname -- "$LIB")/ -APP=`pwd` +CONSOLE=$(dirname -- "$(canonicalize "$0")") +APP=$(dirname "$CONSOLE") -exec php -q "$LIB"cake.php -working "$APP" "$@" - -exit; +exec php -q "$CONSOLE"/cake.php -working "$APP" "$@" +exit diff --git a/lib/Cake/Console/Templates/skel/Console/cake.bat b/lib/Cake/Console/Templates/skel/Console/cake.bat index b28ec8d..e37d4a5 100644 --- a/lib/Cake/Console/Templates/skel/Console/cake.bat +++ b/lib/Cake/Console/Templates/skel/Console/cake.bat @@ -1,19 +1,17 @@ :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :: :: Bake is a shell script for running CakePHP bake script -:: PHP 5 :: :: CakePHP(tm) : Rapid Development Framework (http://cakephp.org) -:: Copyright 2005-2012, Cake Software Foundation, Inc. +:: Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) :: :: Licensed under The MIT License :: Redistributions of files must retain the above copyright notice. :: -:: @copyright Copyright 2005-2012, Cake Software Foundation, Inc. -:: @link http://cakephp.org CakePHP(tm) Project -:: @package app.Console -:: @since CakePHP(tm) v 2.0 -:: @license MIT License (http://www.opensource.org/licenses/mit-license.php) +:: @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) +:: @link http://cakephp.org CakePHP(tm) Project +:: @package app.Console +:: @since CakePHP(tm) v 2.0 :: :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: diff --git a/lib/Cake/Console/Templates/skel/Console/cake.php b/lib/Cake/Console/Templates/skel/Console/cake.php index d3c91b1..f5b262a 100644 --- a/lib/Cake/Console/Templates/skel/Console/cake.php +++ b/lib/Cake/Console/Templates/skel/Console/cake.php @@ -3,31 +3,46 @@ /** * Command-line code generation utility to automate programmer chores. * - * PHP 5 - * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package app.Console * @since CakePHP(tm) v 2.0 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ -$ds = DIRECTORY_SEPARATOR; -$dispatcher = 'Cake' . $ds . 'Console' . $ds . 'ShellDispatcher.php'; + +if (!defined('DS')) { + define('DS', DIRECTORY_SEPARATOR); +} + +$dispatcher = 'Cake' . DS . 'Console' . DS . 'ShellDispatcher.php'; if (function_exists('ini_set')) { $root = dirname(dirname(dirname(__FILE__))); - ini_set('include_path', $root . PATH_SEPARATOR . __CAKE_PATH__ . PATH_SEPARATOR . ini_get('include_path')); + $appDir = basename(dirname(dirname(__FILE__))); + $install = $root . DS . 'lib'; + $composerInstall = $root . DS . $appDir . DS . 'Vendor' . DS . 'cakephp' . DS . 'cakephp' . DS . 'lib'; + + // the following lines differ from its sibling + // /app/Console/cake.php + if (file_exists($composerInstall . DS . $dispatcher)) { + $install = $composerInstall; + } elseif (!file_exists($install . DS . $dispatcher)) { + $install = $root . PATH_SEPARATOR . __CAKE_PATH__; + } + + ini_set('include_path', $install . PATH_SEPARATOR . ini_get('include_path')); + unset($root, $appDir, $install, $composerInstall); } if (!include $dispatcher) { trigger_error('Could not locate CakePHP core files.', E_USER_ERROR); } -unset($paths, $path, $dispatcher, $root, $ds); +unset($dispatcher); return ShellDispatcher::run($argv); diff --git a/lib/Cake/Console/Templates/skel/Controller/AppController.php b/lib/Cake/Console/Templates/skel/Controller/AppController.php index 7aab7e9..db4b9e2 100644 --- a/lib/Cake/Console/Templates/skel/Controller/AppController.php +++ b/lib/Cake/Console/Templates/skel/Controller/AppController.php @@ -5,19 +5,9 @@ * This file is application-wide controller file. You can put all * application-wide controller-related methods here. * - * PHP 5 - * - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) - * - * Licensed under The MIT License - * Redistributions of files must retain the above copyright notice. - * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package app.Controller * @since CakePHP(tm) v 0.2.9 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ App::uses('Controller', 'Controller'); @@ -28,8 +18,8 @@ App::uses('Controller', 'Controller'); * Add your application-wide methods in the class below, your controllers * will inherit them. * - * @package app.Controller - * @link http://book.cakephp.org/2.0/en/controllers.html#the-app-controller + * @package app.Controller + * @link http://book.cakephp.org/2.0/en/controllers.html#the-app-controller */ class AppController extends Controller { } diff --git a/lib/Cake/Console/Templates/skel/Controller/PagesController.php b/lib/Cake/Console/Templates/skel/Controller/PagesController.php index 28edfb6..c97b9a2 100644 --- a/lib/Cake/Console/Templates/skel/Controller/PagesController.php +++ b/lib/Cake/Console/Templates/skel/Controller/PagesController.php @@ -4,21 +4,13 @@ * * This file will render views from views/pages/ * - * PHP 5 - * - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) - * - * Licensed under The MIT License - * Redistributions of files must retain the above copyright notice. - * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package app.Controller * @since CakePHP(tm) v 0.2.9 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ +App::uses('AppController', 'Controller'); + /** * Static content controller * @@ -39,16 +31,22 @@ class PagesController extends AppController { /** * Displays a view * - * @param string What page to display + * @return void + * @throws ForbiddenException When a directory traversal attempt. + * @throws NotFoundException When the view file could not be found + * or MissingViewException in debug mode. */ public function display() { $path = func_get_args(); $count = count($path); if (!$count) { - $this->redirect('/'); + return $this->redirect('/'); } - $page = $subpage = $title = null; + if (in_array('..', $path, true) || in_array('.', $path, true)) { + throw new ForbiddenException(); + } + $page = $subpage = $title_for_layout = null; if (!empty($path[0])) { $page = $path[0]; @@ -57,11 +55,17 @@ class PagesController extends AppController { $subpage = $path[1]; } if (!empty($path[$count - 1])) { - $title = Inflector::humanize($path[$count - 1]); + $title_for_layout = Inflector::humanize($path[$count - 1]); } - $this->set(compact('page', 'subpage')); - $this->set('title_for_layout', $title); - $this->render(implode('/', $path)); - } + $this->set(compact('page', 'subpage', 'title_for_layout')); + try { + $this->render(implode('/', $path)); + } catch (MissingViewException $e) { + if (Configure::read('debug')) { + throw $e; + } + throw new NotFoundException(); + } + } } diff --git a/lib/Cake/Console/Templates/skel/Model/AppModel.php b/lib/Cake/Console/Templates/skel/Model/AppModel.php index 94e5e5f..eef7150 100644 --- a/lib/Cake/Console/Templates/skel/Model/AppModel.php +++ b/lib/Cake/Console/Templates/skel/Model/AppModel.php @@ -5,19 +5,9 @@ * This file is application-wide model file. You can put all * application-wide model-related methods here. * - * PHP 5 - * - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) - * - * Licensed under The MIT License - * Redistributions of files must retain the above copyright notice. - * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package app.Model * @since CakePHP(tm) v 0.2.9 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ App::uses('Model', 'Model'); diff --git a/lib/Cake/Console/Templates/skel/Test/Case/AllTestsTest.php b/lib/Cake/Console/Templates/skel/Test/Case/AllTestsTest.php new file mode 100644 index 0000000..9929fa5 --- /dev/null +++ b/lib/Cake/Console/Templates/skel/Test/Case/AllTestsTest.php @@ -0,0 +1,31 @@ +addTestDirectoryRecursive(TESTS . 'Case'); + return $suite; + } +} diff --git a/lib/Cake/Console/Templates/skel/View/Elements/Flash/default.ctp b/lib/Cake/Console/Templates/skel/View/Elements/Flash/default.ctp new file mode 100644 index 0000000..ce0f613 --- /dev/null +++ b/lib/Cake/Console/Templates/skel/View/Elements/Flash/default.ctp @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/lib/Cake/Console/Templates/skel/View/Emails/html/default.ctp b/lib/Cake/Console/Templates/skel/View/Emails/html/default.ctp index 2d00c3d..a1333dc 100644 --- a/lib/Cake/Console/Templates/skel/View/Emails/html/default.ctp +++ b/lib/Cake/Console/Templates/skel/View/Emails/html/default.ctp @@ -1,25 +1,22 @@ ' . $line . '

'; -endforeach; -?> \ No newline at end of file + echo '

' . $line . "

\n"; +endforeach; \ No newline at end of file diff --git a/lib/Cake/Console/Templates/skel/View/Emails/text/default.ctp b/lib/Cake/Console/Templates/skel/View/Emails/text/default.ctp index 8b5e8c8..7f88324 100644 --- a/lib/Cake/Console/Templates/skel/View/Emails/text/default.ctp +++ b/lib/Cake/Console/Templates/skel/View/Emails/text/default.ctp @@ -1,19 +1,17 @@ \ No newline at end of file diff --git a/lib/Cake/Console/Templates/skel/View/Errors/error400.ctp b/lib/Cake/Console/Templates/skel/View/Errors/error400.ctp index 6d50860..6c84d88 100644 --- a/lib/Cake/Console/Templates/skel/View/Errors/error400.ctp +++ b/lib/Cake/Console/Templates/skel/View/Errors/error400.ctp @@ -1,22 +1,11 @@ -

+

:

0 ): +if (Configure::read('debug') > 0): echo $this->element('exception_stack_trace'); endif; -?> diff --git a/lib/Cake/Console/Templates/skel/View/Errors/error500.ctp b/lib/Cake/Console/Templates/skel/View/Errors/error500.ctp index 4e1f36e..339e140 100644 --- a/lib/Cake/Console/Templates/skel/View/Errors/error500.ctp +++ b/lib/Cake/Console/Templates/skel/View/Errors/error500.ctp @@ -1,28 +1,16 @@ -

+

:

0 ): +if (Configure::read('debug') > 0): echo $this->element('exception_stack_trace'); endif; -?> diff --git a/lib/Cake/Console/Templates/skel/View/Helper/AppHelper.php b/lib/Cake/Console/Templates/skel/View/Helper/AppHelper.php index caceda8..f9cbd90 100644 --- a/lib/Cake/Console/Templates/skel/View/Helper/AppHelper.php +++ b/lib/Cake/Console/Templates/skel/View/Helper/AppHelper.php @@ -5,20 +5,11 @@ * This file is application-wide helper file. You can put all * application-wide helper-related methods here. * - * PHP 5 - * - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) - * - * Licensed under The MIT License - * Redistributions of files must retain the above copyright notice. - * - * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package app.View.Helper * @since CakePHP(tm) v 0.2.9 - * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ + App::uses('Helper', 'View'); /** diff --git a/lib/Cake/Console/Templates/skel/View/Layouts/Emails/html/default.ctp b/lib/Cake/Console/Templates/skel/View/Layouts/Emails/html/default.ctp index 12a9171..c984875 100644 --- a/lib/Cake/Console/Templates/skel/View/Layouts/Emails/html/default.ctp +++ b/lib/Cake/Console/Templates/skel/View/Layouts/Emails/html/default.ctp @@ -1,31 +1,18 @@ - - <?php echo $title_for_layout; ?> + <?php echo $this->fetch('title'); ?> - fetch('content'); ?>

This email was sent using the CakePHP Framework

- + \ No newline at end of file diff --git a/lib/Cake/Console/Templates/skel/View/Layouts/Emails/text/default.ctp b/lib/Cake/Console/Templates/skel/View/Layouts/Emails/text/default.ctp index f914b3d..5396158 100644 --- a/lib/Cake/Console/Templates/skel/View/Layouts/Emails/text/default.ctp +++ b/lib/Cake/Console/Templates/skel/View/Layouts/Emails/text/default.ctp @@ -1,22 +1,19 @@ - fetch('content'); ?> This email was sent using the CakePHP Framework, http://cakephp.org. diff --git a/lib/Cake/Console/Templates/skel/View/Layouts/ajax.ctp b/lib/Cake/Console/Templates/skel/View/Layouts/ajax.ctp index 9dc5ee5..f2338e6 100644 --- a/lib/Cake/Console/Templates/skel/View/Layouts/ajax.ctp +++ b/lib/Cake/Console/Templates/skel/View/Layouts/ajax.ctp @@ -1,19 +1,8 @@ fetch('content'); ?> diff --git a/lib/Cake/Console/Templates/skel/View/Layouts/default.ctp b/lib/Cake/Console/Templates/skel/View/Layouts/default.ctp index 4aab010..a2c3038 100644 --- a/lib/Cake/Console/Templates/skel/View/Layouts/default.ctp +++ b/lib/Cake/Console/Templates/skel/View/Layouts/default.ctp @@ -1,28 +1,19 @@ - - + + Html->charset(); ?> - <?php echo __('CakePHP: the rapid development php framework:'); ?> - <?php echo $title_for_layout; ?> + <?php echo $cakeDescription ?>: + <?php echo $this->fetch('title'); ?> Html->meta('icon'); @@ -37,7 +28,7 @@
@@ -47,7 +38,7 @@