diff --git a/README.md b/README.md index 407efb86c9353c1ae88f81ce72b4c8a3ae788e30..aeaa4032a07c611652e21110013020ae434f6941 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,14 @@ rainloop-nextcloud is a plugin for Nextcloud to use the excellent Rainloop webma ## Which branch for which version of Nextcloud? -The nc13 branch corresponds to the working version of the plugin for Nextcloud 10 to Nextcloud 13. This is the stable version for now. -The nc14 branch corresponds to a beta version of the plugin for Nextcloud 14, with work and testing in progress. - +The nc13 branch corresponds to the working version of the plugin for Nextcloud 10 to Nextcloud 13. +The nc14 branch corresponds to a beta version of the plugin for Nextcloud 14. All the changes of nc14 branch were merged into master when it was deemed suitable for production. +The master branch corresponds to the latest stable version of the plugin. + +Thank you to all contributors to Rainloop for nextcloud: +- Rainloop Team, who initiated it +- Tab Fitts (@tabp0le) +- Nextgen Networks (@nextgen-networks) ## How to Install diff --git a/rainloop/INSTALL b/rainloop/INSTALL index 68a9f1661c28f015b80f3c9075fcb04894f06be5..6d2a88aeef025e0e7d47a2bf926ec190282de9c2 100755 --- a/rainloop/INSTALL +++ b/rainloop/INSTALL @@ -1,19 +1,18 @@ -************************************************************************ -* -* Nextcloud - RainLoop Webmail package -* -* @author RainLoop Team & Pierre-Alain Bandinelli -* -* -************************************************************************ - -REQUIREMENTS: -- nextCloud version 10 to 13 - - -INSTALL & CONFIGURATION: -Start within Nextcloud, and click on the "+ Apps" button in the upper-left corner dropdown menu: -Then, enable the Rainloop plugin that is in the "Social & communication" section. -After a quick wait, Rainloop is installed. Even if it is really attractive, it is too soon to click on the newly appeared "Email" icon in the apps list. You should configure Rainloop before using it (which makes some sense, doesn'it): go to Nextcloud admin panel (upper-right corner dropdown menu) and go to "Additionnal settings". There click on the "Go to RainLoop Webmail admin panel". -In the Rainloop admin prompt, the default login is "admin" and the default password is "12345". No need to advise you to change it once in the admin panel! -This is it, you are now free to configure Rainloop as you wish. One important point is the Domains section when you will set up the IMAP/SMTP parameters that shall be associated with the email adresses of your users. +************************************************************************ +* +* Nextcloud - RainLoop Webmail package +* +* @author RainLoop Team, Nextgen-Networks (@nextgen-networks), Tab Fitts (@tabp0le), Pierre-Alain Bandinelli (@pierre-alain-b) +* +************************************************************************ + +REQUIREMENTS: +- nextCloud version 14 and above + + +INSTALL & CONFIGURATION: +Start within Nextcloud, and click on the "+ Apps" button in the upper-left corner dropdown menu: +Then, enable the Rainloop plugin that is in the "Social & communication" section. +After a quick wait, Rainloop is installed. Even if it is really attractive, it is too soon to click on the newly appeared "Email" icon in the apps list. You should configure Rainloop before using it (which makes some sense, doesn'it): go to Nextcloud admin panel (upper-right corner dropdown menu) and go to "Additionnal settings". There click on the "Go to RainLoop Webmail admin panel". +In the Rainloop admin prompt, the default login is "admin" and the default password is "12345". No need to advise you to change it once in the admin panel! +This is it, you are now free to configure Rainloop as you wish. One important point is the Domains section when you will set up the IMAP/SMTP parameters that shall be associated with the email adresses of your users. diff --git a/rainloop/VERSION b/rainloop/VERSION index 831446cbd27a6de403344b21c9fa93a25357f43d..e0ea36feef6e828ce8587989537a827d0c3c98ed 100755 --- a/rainloop/VERSION +++ b/rainloop/VERSION @@ -1 +1 @@ -5.1.0 +6.0 diff --git a/rainloop/admin.php b/rainloop/admin.php index eda65df51a749730665c788f307e6cd4e273dc77..ff67530a77d84b763c8bb03ed4fe8195e4d5fca7 100755 --- a/rainloop/admin.php +++ b/rainloop/admin.php @@ -3,10 +3,9 @@ /** * Nextcloud - RainLoop mail plugin * - * @author RainLoop Team - * @copyright 2016 RainLoop Team + * @author RainLoop Team, Nextgen-Networks (@nextgen-networks), Tab Fitts (@tabp0le), Pierre-Alain Bandinelli (@pierre-alain-b) * - * https://github.com/RainLoop/rainloop-webmail/tree/master/build/owncloud + * Based initially on https://github.com/RainLoop/rainloop-webmail/tree/master/build/owncloud */ OCP\User::checkAdminUser(); @@ -15,5 +14,5 @@ OCP\Util::addScript('rainloop', 'admin'); $oTemplate = new OCP\Template('rainloop', 'admin-local'); $oTemplate->assign('rainloop-admin-panel-link', OC_RainLoop_Helper::getAppUrl().'?admin'); -$oTemplate->assign('rainloop-autologin', OCP\Config::getAppValue('rainloop', 'rainloop-autologin', false)); +$oTemplate->assign('rainloop-autologin', \OC::$server->getConfig()->getAppValue('rainloop', 'rainloop-autologin', false)); return $oTemplate->fetchPage(); diff --git a/rainloop/ajax/admin.php b/rainloop/ajax/admin.php index 788a4dacc90ac3f7f83afc552b7f955b0fb8acf5..588136de09c338e6fd8017c573cc94f041f0424c 100755 --- a/rainloop/ajax/admin.php +++ b/rainloop/ajax/admin.php @@ -3,15 +3,14 @@ /** * Nextcloud - RainLoop mail plugin * - * @author RainLoop Team - * @copyright 2016 RainLoop Team + * @author RainLoop Team, Nextgen-Networks (@nextgen-networks), Tab Fitts (@tabp0le), Pierre-Alain Bandinelli (@pierre-alain-b) * - * https://github.com/RainLoop/rainloop-webmail/tree/master/build/owncloud + * Based initially on https://github.com/RainLoop/rainloop-webmail/tree/master/build/owncloud */ -OCP\JSON::checkAdminUser(); -OCP\JSON::checkAppEnabled('rainloop'); -OCP\JSON::callCheck(); +\OC_JSON::checkAdminUser(); +\OC_JSON::checkAppEnabled('rainloop'); +\OC_JSON::callCheck(); $sUrl = ''; $sPath = ''; @@ -19,10 +18,10 @@ $bAutologin = false; if (isset($_POST['appname']) && 'rainloop' === $_POST['appname']) { - OCP\Config::setAppValue('rainloop', 'rainloop-autologin', isset($_POST['rainloop-autologin']) ? + \OC::$server->getConfig()->setAppValue('rainloop', 'rainloop-autologin', isset($_POST['rainloop-autologin']) ? '1' === $_POST['rainloop-autologin'] : false); - $bAutologin = OCP\Config::getAppValue('rainloop', 'rainloop-autologin', false); + $bAutologin = \OC::$server->getConfig()->getAppValue('rainloop', 'rainloop-autologin', false); } else { @@ -32,5 +31,5 @@ else } sleep(1); -OCP\JSON::success(array('Message' => 'Saved successfully')); +\OC_JSON::success(array('Message' => 'Saved successfully')); return true; diff --git a/rainloop/ajax/personal.php b/rainloop/ajax/personal.php index 3db7373823d04d110c3e88212f02459909c49f6c..4805f8f428986843b493a13bcfc156d52a8fec70 100755 --- a/rainloop/ajax/personal.php +++ b/rainloop/ajax/personal.php @@ -3,15 +3,14 @@ /** * Nextcloud - RainLoop mail plugin * - * @author RainLoop Team - * @copyright 2016 RainLoop Team + * @author RainLoop Team, Nextgen-Networks (@nextgen-networks), Tab Fitts (@tabp0le), Pierre-Alain Bandinelli (@pierre-alain-b) * - * https://github.com/RainLoop/rainloop-webmail/tree/master/build/owncloud + * Based initially on https://github.com/RainLoop/rainloop-webmail/tree/master/build/owncloud */ -OCP\JSON::checkLoggedIn(); -OCP\JSON::checkAppEnabled('rainloop'); -OCP\JSON::callCheck(); +\OC_JSON::checkLoggedIn(); +\OC_JSON::checkAppEnabled('rainloop'); +\OC_JSON::callCheck(); $sEmail = ''; $sLogin = ''; @@ -22,18 +21,18 @@ if (isset($_POST['appname'], $_POST['rainloop-password'], $_POST['rainloop-email $sPostEmail = $_POST['rainloop-email']; - OCP\Config::setUserValue($sUser, 'rainloop', 'rainloop-email', $sPostEmail); + \OC::$server->getConfig()->setUserValue($sUser, 'rainloop', 'rainloop-email', $sPostEmail); $sPass = $_POST['rainloop-password']; if ('******' !== $sPass && '' !== $sPass) { include_once OC_App::getAppPath('rainloop').'/lib/RainLoopHelper.php'; - OCP\Config::setUserValue($sUser, 'rainloop', 'rainloop-password', + \OC::$server->getConfig()->setUserValue($sUser, 'rainloop', 'rainloop-password', OC_RainLoop_Helper::encodePassword($sPass, md5($sPostEmail))); } - $sEmail = OCP\Config::getUserValue($sUser, 'rainloop', 'rainloop-email', ''); + $sEmail = \OC::$server->getConfig()->getUserValue($sUser, 'rainloop', 'rainloop-email', ''); } else { @@ -43,5 +42,5 @@ else } sleep(1); -OCP\JSON::success(array('Message' => 'Saved successfully', 'Email' => $sEmail)); +\OC_JSON::success(array('Message' => 'Saved successfully', 'Email' => $sEmail)); return true; diff --git a/rainloop/app.php b/rainloop/app.php index a945a442245da65d543b02a0edb8c7d928ac9cc9..3139032587c8d169cdceb89ac7c2ffc4227cf1c0 100755 --- a/rainloop/app.php +++ b/rainloop/app.php @@ -1,50 +1,58 @@ -getContentSecurityPolicyNonceManager()->getNonce().'\'; ' - . 'style-src \'self\' \'unsafe-inline\'; ' - . 'frame-src *; ' - . 'img-src * data: blob:; ' - . 'font-src \'self\' data:; ' - . 'media-src *; ' - . 'connect-src *; ' - . 'object-src \'self\'; ' - . 'base-uri \'self\'; '; -header('Content-Security-Policy:' . $policy); - -if (@file_exists(__DIR__.'/app/index.php')) -{ - include_once OC_App::getAppPath('rainloop').'/lib/RainLoopHelper.php'; - - OC_RainLoop_Helper::regRainLoopDataFunction(); - - if (isset($_GET['OwnCloudAuth'])) - { - $sEmail = ''; - $sEncodedPassword = ''; - - $sUser = OCP\User::getUser(); - - if (OCP\Config::getAppValue('rainloop', 'rainloop-autologin', false)) - { - $sEmail = $sUser; - $sEncodedPassword = OCP\Config::getUserValue($sUser, 'rainloop', 'rainloop-autologin-password', ''); - } - else - { - $sEmail = OCP\Config::getUserValue($sUser, 'rainloop', 'rainloop-email', ''); - $sEncodedPassword = OCP\Config::getUserValue($sUser, 'rainloop', 'rainloop-password', ''); - } - - $sDecodedPassword = OC_RainLoop_Helper::decodePassword($sEncodedPassword, md5($sEmail)); - - $_ENV['___rainloop_owncloud_email'] = $sEmail; - $_ENV['___rainloop_owncloud_password'] = $sDecodedPassword; - } - - include __DIR__.'/app/index.php'; -} +getContentSecurityPolicyNonceManager()->getNonce().'\'; ' + . 'style-src \'self\' \'unsafe-inline\'; ' + . 'frame-src *; ' + . 'img-src * data: blob:; ' + . 'font-src \'self\' data:; ' + . 'media-src *; ' + . 'connect-src *; ' + . 'object-src \'self\'; ' + . 'base-uri \'self\'; '; +header('Content-Security-Policy:' . $policy); + +if (@file_exists(__DIR__.'/app/index.php')) +{ + include_once OC_App::getAppPath('rainloop').'/lib/RainLoopHelper.php'; + + OC_RainLoop_Helper::regRainLoopDataFunction(); + + if (isset($_GET['OwnCloudAuth'])) + { + $sEmail = ''; + $sEncodedPassword = ''; + + $sUser = OCP\User::getUser(); + + if (\OC::$server->getConfig()->getAppValue('rainloop', 'rainloop-autologin', false)) + { + $sEmail = $sUser; + $sEncodedPassword = \OC::$server->getConfig()->getUserValue($sUser, 'rainloop', 'rainloop-autologin-password', ''); + } + else + { + $sEmail = \OC::$server->getConfig()->getUserValue($sUser, 'rainloop', 'rainloop-email', ''); + $sEncodedPassword = \OC::$server->getConfig()->getUserValue($sUser, 'rainloop', 'rainloop-password', ''); + } + + $sDecodedPassword = OC_RainLoop_Helper::decodePassword($sEncodedPassword, md5($sEmail)); + + $_ENV['___rainloop_owncloud_email'] = $sEmail; + $_ENV['___rainloop_owncloud_password'] = $sDecodedPassword; + } + + include __DIR__.'/app/index.php'; +} diff --git a/rainloop/app/data/EMPTY b/rainloop/app/data/EMPTY index 32bd932f355b1b5f394c25861cde21a823665244..6f165bc1b06167bf9ab68b9e7456cb597e092f09 100644 --- a/rainloop/app/data/EMPTY +++ b/rainloop/app/data/EMPTY @@ -1 +1 @@ -1.12.0 \ No newline at end of file +1.12.1 \ No newline at end of file diff --git a/rainloop/app/data/VERSION b/rainloop/app/data/VERSION index 32bd932f355b1b5f394c25861cde21a823665244..6f165bc1b06167bf9ab68b9e7456cb597e092f09 100644 --- a/rainloop/app/data/VERSION +++ b/rainloop/app/data/VERSION @@ -1 +1 @@ -1.12.0 \ No newline at end of file +1.12.1 \ No newline at end of file diff --git a/rainloop/app/index.php b/rainloop/app/index.php index 91bc1257a8c0cbd612b106db2cd38c1a3bbb077b..95943c5c7c49155e7a3e0e2ebb2cee69049ddbdf 100644 --- a/rainloop/app/index.php +++ b/rainloop/app/index.php @@ -2,7 +2,7 @@ if (!defined('APP_VERSION')) { - define('APP_VERSION', '1.12.0'); + define('APP_VERSION', '1.12.1'); define('APP_VERSION_TYPE', 'community'); define('APP_INDEX_ROOT_FILE', __FILE__); define('APP_INDEX_ROOT_PATH', str_replace('\\', '/', rtrim(dirname(__FILE__), '\\/').'/')); diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Adapter/AdapterInterface.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Adapter/AdapterInterface.php deleted file mode 100644 index f3c035e2b46683f47f0278c5e51530b3aa311404..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Adapter/AdapterInterface.php +++ /dev/null @@ -1,23 +0,0 @@ -multi = $multiHandle; - $this->handles = new \SplObjectStorage(); - $this->throwsExceptions = $throwsExceptions; - $this->pending = $pending; - } - - /** - * Find a transaction for a given curl handle - * - * @param resource $handle Curl handle - * - * @return TransactionInterface - * @throws AdapterException if a transaction is not found - */ - public function findTransaction($handle) - { - foreach ($this->handles as $transaction) { - if ($this->handles[$transaction] === $handle) { - return $transaction; - } - } - - throw new AdapterException('No curl handle was found'); - } - - /** - * Returns true if there are any remaining pending transactions - * - * @return bool - */ - public function hasPending() - { - return $this->pending && $this->pending->valid(); - } - - /** - * Pop the next transaction from the transaction queue - * - * @return TransactionInterface|null - */ - public function nextPending() - { - if (!$this->hasPending()) { - return null; - } - - $current = $this->pending->current(); - $this->pending->next(); - - return $current; - } - - /** - * Checks if the batch is to throw exceptions on error - * - * @return bool - */ - public function throwsExceptions() - { - return $this->throwsExceptions; - } - - /** - * Get the curl_multi handle - * - * @return resource - */ - public function getMultiHandle() - { - return $this->multi; - } - - /** - * Add a transaction to the multi handle - * - * @param TransactionInterface $transaction Transaction to add - * @param resource $handle Resource to use with the handle - * - * @throws AdapterException If the handle is already registered - */ - public function addTransaction(TransactionInterface $transaction, $handle) - { - if (isset($this->handles[$transaction])) { - throw new AdapterException('Transaction already registered'); - } - - $code = curl_multi_add_handle($this->multi, $handle); - if ($code != CURLM_OK) { - MultiAdapter::throwMultiError($code); - } - - $this->handles[$transaction] = $handle; - } - - /** - * Remove a transaction and associated handle from the context - * - * @param TransactionInterface $transaction Transaction to remove - * - * @return array Returns the curl_getinfo array - * @throws AdapterException if the transaction is not found - */ - public function removeTransaction(TransactionInterface $transaction) - { - if (!isset($this->handles[$transaction])) { - throw new AdapterException('Transaction not registered'); - } - - $handle = $this->handles[$transaction]; - - $code = curl_multi_remove_handle($this->multi, $handle); - if ($code != CURLM_OK) { - MultiAdapter::throwMultiError($code); - } - - $info = curl_getinfo($handle); - curl_close($handle); - unset($this->handles[$transaction]); - - return $info; - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Adapter/Curl/CurlAdapter.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Adapter/Curl/CurlAdapter.php deleted file mode 100644 index 0f12035317157ba60d1f158a981a5c45b671f51d..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Adapter/Curl/CurlAdapter.php +++ /dev/null @@ -1,142 +0,0 @@ -handles = $this->ownedHandles = []; - $this->messageFactory = $messageFactory; - $this->curlFactory = isset($options['handle_factory']) - ? $options['handle_factory'] - : new CurlFactory(); - $this->maxHandles = isset($options['max_handles']) - ? $options['max_handles'] - : 5; - } - - public function __destruct() - { - foreach ($this->handles as $handle) { - if (is_resource($handle)) { - curl_close($handle); - } - } - } - - public function send(TransactionInterface $transaction) - { - RequestEvents::emitBefore($transaction); - if ($response = $transaction->getResponse()) { - return $response; - } - - $factory = $this->curlFactory; - $handle = $factory( - $transaction, - $this->messageFactory, - $this->checkoutEasyHandle() - ); - - curl_exec($handle); - $info = curl_getinfo($handle); - $info['curl_result'] = curl_errno($handle); - - if ($info['curl_result']) { - $this->handleError($transaction, $info, $handle); - } else { - $this->releaseEasyHandle($handle); - RequestEvents::emitComplete($transaction, $info); - } - - return $transaction->getResponse(); - } - - private function handleError( - TransactionInterface $transaction, - $info, - $handle - ) { - $error = curl_error($handle); - $this->releaseEasyHandle($handle); - RequestEvents::emitError( - $transaction, - new AdapterException("cURL error {$info['curl_result']}: {$error}"), - $info - ); - } - - private function checkoutEasyHandle() - { - // Find an unused handle in the cache - if (false !== ($key = array_search(false, $this->ownedHandles, true))) { - $this->ownedHandles[$key] = true; - return $this->handles[$key]; - } - - // Add a new handle - $handle = curl_init(); - $id = (int) $handle; - $this->handles[$id] = $handle; - $this->ownedHandles[$id] = true; - - return $handle; - } - - private function releaseEasyHandle($handle) - { - $id = (int) $handle; - if (count($this->ownedHandles) > $this->maxHandles) { - curl_close($this->handles[$id]); - unset($this->handles[$id], $this->ownedHandles[$id]); - } else { - curl_reset($handle); - $this->ownedHandles[$id] = false; - } - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Adapter/Curl/CurlFactory.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Adapter/Curl/CurlFactory.php deleted file mode 100644 index f1cb393a770a88238137ee1b19ccadb0ffc34970..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Adapter/Curl/CurlFactory.php +++ /dev/null @@ -1,331 +0,0 @@ -getRequest(); - $mediator = new RequestMediator($transaction, $messageFactory); - $options = $this->getDefaultOptions($request, $mediator); - $this->applyMethod($request, $options); - $this->applyTransferOptions($request, $mediator, $options); - $this->applyHeaders($request, $options); - unset($options['_headers']); - - // Add adapter options from the request's configuration options - if ($config = $request->getConfig()['curl']) { - $options = $this->applyCustomCurlOptions($config, $options); - } - - if (!$handle) { - $handle = curl_init(); - } - - curl_setopt_array($handle, $options); - - return $handle; - } - - protected function getDefaultOptions( - RequestInterface $request, - RequestMediator $mediator - ) { - $url = $request->getUrl(); - - // Strip fragment from URL. See: - // https://github.com/guzzle/guzzle/issues/453 - if (($pos = strpos($url, '#')) !== false) { - $url = substr($url, 0, $pos); - } - - $config = $request->getConfig(); - $options = array( - CURLOPT_URL => $url, - CURLOPT_CONNECTTIMEOUT => $config['connect_timeout'] ?: 150, - CURLOPT_RETURNTRANSFER => false, - CURLOPT_HEADER => false, - CURLOPT_WRITEFUNCTION => array($mediator, 'writeResponseBody'), - CURLOPT_HEADERFUNCTION => array($mediator, 'receiveResponseHeader'), - CURLOPT_READFUNCTION => array($mediator, 'readRequestBody'), - CURLOPT_HTTP_VERSION => $request->getProtocolVersion() === '1.0' - ? CURL_HTTP_VERSION_1_0 : CURL_HTTP_VERSION_1_1, - CURLOPT_SSL_VERIFYPEER => 1, - CURLOPT_SSL_VERIFYHOST => 2, - '_headers' => $request->getHeaders() - ); - - if (defined('CURLOPT_PROTOCOLS')) { - // Allow only HTTP and HTTPS protocols - $options[CURLOPT_PROTOCOLS] = CURLPROTO_HTTP | CURLPROTO_HTTPS; - } - - // Add CURLOPT_ENCODING if Accept-Encoding header is provided - if ($request->hasHeader('Accept-Encoding')) { - $options[CURLOPT_ENCODING] = $request->getHeader('Accept-Encoding'); - // Let cURL set the Accept-Encoding header. Without this change - // curl could add a duplicate value. - $this->removeHeader('Accept-Encoding', $options); - } - - return $options; - } - - private function applyMethod(RequestInterface $request, array &$options) - { - $method = $request->getMethod(); - if ($method == 'HEAD') { - $options[CURLOPT_NOBODY] = true; - unset($options[CURLOPT_WRITEFUNCTION], $options[CURLOPT_READFUNCTION]); - } else { - $options[CURLOPT_CUSTOMREQUEST] = $method; - if (!$request->getBody()) { - unset($options[CURLOPT_READFUNCTION]); - } else { - $this->applyBody($request, $options); - } - } - } - - private function applyBody(RequestInterface $request, array &$options) - { - if ($request->hasHeader('Content-Length')) { - $size = (int) $request->getHeader('Content-Length'); - } else { - $size = null; - } - - $request->getBody()->seek(0); - - // You can send the body as a string using curl's CURLOPT_POSTFIELDS - if (($size !== null && $size < 32768) || - isset($request->getConfig()['curl']['body_as_string']) - ) { - $options[CURLOPT_POSTFIELDS] = $request->getBody()->getContents(); - // Don't duplicate the Content-Length header - $this->removeHeader('Content-Length', $options); - $this->removeHeader('Transfer-Encoding', $options); - } else { - $options[CURLOPT_UPLOAD] = true; - // Let cURL handle setting the Content-Length header - if ($size !== null) { - $options[CURLOPT_INFILESIZE] = $size; - $this->removeHeader('Content-Length', $options); - } - } - - // If the Expect header is not present, prevent curl from adding it - if (!$request->hasHeader('Expect')) { - $options[CURLOPT_HTTPHEADER][] = 'Expect:'; - } - } - - private function applyHeaders(RequestInterface $request, array &$options) - { - foreach ($options['_headers'] as $name => $values) { - $options[CURLOPT_HTTPHEADER][] = $name . ': ' . implode(', ', $values); - } - - // Remove the Expect header if one was not set - if (!$request->hasHeader('Accept')) { - $options[CURLOPT_HTTPHEADER][] = 'Accept:'; - } - } - - private function applyTransferOptions( - RequestInterface $request, - RequestMediator $mediator, - array &$options - ) { - static $methods; - if (!$methods) { - $methods = array_flip(get_class_methods(__CLASS__)); - } - - foreach ($request->getConfig()->toArray() as $key => $value) { - $method = "add_{$key}"; - if (isset($methods[$method])) { - $this->{$method}($request, $mediator, $options, $value); - } - } - } - - private function add_debug( - RequestInterface $request, - RequestMediator $mediator, - &$options, - $value - ) { - if ($value) { - $options[CURLOPT_STDERR] = is_resource($value) ? $value : STDOUT; - $options[CURLOPT_VERBOSE] = true; - } - } - - private function add_proxy( - RequestInterface $request, - RequestMediator $mediator, - &$options, - $value - ) { - if (!is_array($value)) { - $options[CURLOPT_PROXY] = $value; - } else { - $scheme = $request->getScheme(); - if (isset($value[$scheme])) { - $options[CURLOPT_PROXY] = $value[$scheme]; - } - } - } - - private function add_timeout( - RequestInterface $request, - RequestMediator $mediator, - &$options, - $value - ) { - $options[CURLOPT_TIMEOUT_MS] = $value * 1000; - } - - private function add_connect_timeout( - RequestInterface $request, - RequestMediator $mediator, - &$options, - $value - ) { - $options[CURLOPT_CONNECTTIMEOUT_MS] = $value * 1000; - } - - private function add_verify( - RequestInterface $request, - RequestMediator $mediator, - &$options, - $value - ) { - if ($value === false) { - unset($options[CURLOPT_CAINFO]); - $options[CURLOPT_SSL_VERIFYHOST] = 0; - $options[CURLOPT_SSL_VERIFYPEER] = false; - } elseif ($value === true || is_string($value)) { - $options[CURLOPT_SSL_VERIFYHOST] = 2; - $options[CURLOPT_SSL_VERIFYPEER] = true; - if ($value !== true) { - if (!file_exists($value)) { - throw new AdapterException('SSL certificate authority file' - . " not found: {$value}"); - } - $options[CURLOPT_CAINFO] = $value; - } - } - } - - private function add_cert( - RequestInterface $request, - RequestMediator $mediator, - &$options, - $value - ) { - if (!file_exists($value)) { - throw new AdapterException("SSL certificate not found: {$value}"); - } - - $options[CURLOPT_SSLCERT] = $value; - } - - private function add_ssl_key( - RequestInterface $request, - RequestMediator $mediator, - &$options, - $value - ) { - if (is_array($value)) { - $options[CURLOPT_SSLKEYPASSWD] = $value[1]; - $value = $value[0]; - } - - if (!file_exists($value)) { - throw new AdapterException("SSL private key not found: {$value}"); - } - - $options[CURLOPT_SSLKEY] = $value; - } - - private function add_save_to( - RequestInterface $request, - RequestMediator $mediator, - &$options, - $value - ) { - $mediator->setResponseBody(is_string($value) - ? Stream\create(fopen($value, 'w')) - : Stream\create($value)); - } - - /** - * Takes an array of curl options specified in the 'curl' option of a - * request's configuration array and maps them to CURLOPT_* options. - * - * This method is only called when a request has a 'curl' config setting. - * Array key strings that start with CURL that have a matching constant - * value will be automatically converted to the matching constant. - * - * @param array $config Configuration array of custom curl option - * @param array $options Array of existing curl options - * - * @return array Returns a new array of curl options - */ - private function applyCustomCurlOptions(array $config, array $options) - { - unset($config['body_as_string']); - $curlOptions = []; - - // Map curl constant strings to defined values - foreach ($config as $key => $value) { - if (defined($key) && substr($key, 0, 4) === 'CURL') { - $key = constant($key); - } - $curlOptions[$key] = $value; - } - - return $curlOptions + $options; - } - - /** - * Remove a header from the options array - * - * @param string $name Case-insensitive header to remove - * @param array $options Array of options to modify - */ - private function removeHeader($name, array &$options) - { - foreach (array_keys($options['_headers']) as $key) { - if (!strcasecmp($key, $name)) { - unset($options['_headers'][$key]); - return; - } - } - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Adapter/Curl/MultiAdapter.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Adapter/Curl/MultiAdapter.php deleted file mode 100644 index 306459569c8003109baaf7a9a2ba794ce23ab850..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Adapter/Curl/MultiAdapter.php +++ /dev/null @@ -1,284 +0,0 @@ -messageFactory = $messageFactory; - $this->curlFactory = isset($options['handle_factory']) - ? $options['handle_factory'] - : new CurlFactory(); - - if (isset($options['select_timeout'])) { - $this->selectTimeout = $options['select_timeout']; - } elseif (isset($_SERVER[self::ENV_SELECT_TIMEOUT])) { - $this->selectTimeout = $_SERVER[self::ENV_SELECT_TIMEOUT]; - } else { - $this->selectTimeout = 1; - } - } - - public function __destruct() - { - foreach ($this->multiHandles as $handle) { - if (is_resource($handle)) { - curl_multi_close($handle); - } - } - } - - /** - * Throw an exception for a cURL multi response - * - * @param int $code Curl response code - * @throws AdapterException - */ - public static function throwMultiError($code) - { - $buffer = function_exists('curl_multi_strerror') - ? curl_multi_strerror($code) - : self::ERROR_STR; - - throw new AdapterException(sprintf('cURL error %s: %s', $code, $buffer)); - } - - public function send(TransactionInterface $transaction) - { - $context = new BatchContext($this->checkoutMultiHandle(), true); - $this->addHandle($transaction, $context); - $this->perform($context); - - return $transaction->getResponse(); - } - - public function sendAll(\Iterator $transactions, $parallel) - { - $context = new BatchContext( - $this->checkoutMultiHandle(), - false, - $transactions - ); - - foreach (new \LimitIterator($transactions, 0, $parallel) as $trans) { - $this->addHandle($trans, $context); - } - - $this->perform($context); - } - - private function perform(BatchContext $context) - { - // The first curl_multi_select often times out no matter what, but is - // usually required for fast transfers. - $active = false; - $multi = $context->getMultiHandle(); - - do { - while (($mrc = curl_multi_exec($multi, $active)) == CURLM_CALL_MULTI_PERFORM); - if ($mrc != CURLM_OK && $mrc != CURLM_CALL_MULTI_PERFORM) { - self::throwMultiError($mrc); - } - // Need to check if there are pending transactions before processing - // them so that we don't bail from the loop too early. - $pending = $context->hasPending(); - $this->processMessages($context); - if ($active && curl_multi_select($multi, $this->selectTimeout) === -1) { - // Perform a usleep if a select returns -1. - // See: https://bugs.php.net/bug.php?id=61141 - usleep(250); - } - } while ($active || $pending); - - $this->releaseMultiHandle($multi); - } - - private function processMessages(BatchContext $context) - { - $multi = $context->getMultiHandle(); - - while ($done = curl_multi_info_read($multi)) { - $transaction = $context->findTransaction($done['handle']); - $this->processResponse($transaction, $done, $context); - // Add the next transaction if there are more in the queue - if ($next = $context->nextPending()) { - $this->addHandle($next, $context); - } - } - } - - private function processResponse( - TransactionInterface $transaction, - array $curl, - BatchContext $context - ) { - $info = $context->removeTransaction($transaction); - - try { - if (!$this->isCurlException($transaction, $curl, $context, $info)) { - RequestEvents::emitComplete($transaction, $info); - } - } catch (RequestException $e) { - $this->throwException($e, $context); - } - } - - private function addHandle( - TransactionInterface $transaction, - BatchContext $context - ) { - try { - RequestEvents::emitBefore($transaction); - // Only transfer if the request was not intercepted - if (!$transaction->getResponse()) { - $factory = $this->curlFactory; - $context->addTransaction( - $transaction, - $factory($transaction, $this->messageFactory) - ); - } - } catch (RequestException $e) { - $this->throwException($e, $context); - } - } - - private function isCurlException( - TransactionInterface $transaction, - array $curl, - BatchContext $context, - array $info - ) { - if (CURLM_OK == $curl['result'] || - CURLM_CALL_MULTI_PERFORM == $curl['result'] - ) { - return false; - } - - $request = $transaction->getRequest(); - try { - // Send curl stats along if they are available - $stats = ['curl_result' => $curl['result']] + $info; - RequestEvents::emitError( - $transaction, - new RequestException( - sprintf( - '[curl] (#%s) %s [url] %s', - $curl['result'], - function_exists('curl_strerror') - ? curl_strerror($curl['result']) - : self::ERROR_STR, - $request->getUrl() - ), - $request - ), - $stats - ); - } catch (RequestException $e) { - $this->throwException($e, $context); - } - - return true; - } - - private function throwException(RequestException $e, BatchContext $context) - { - if ($context->throwsExceptions()) { - $this->releaseMultiHandle($context->getMultiHandle()); - throw $e; - } - } - - /** - * Returns a curl_multi handle from the cache or creates a new one - * - * @return resource - */ - private function checkoutMultiHandle() - { - // Find an unused handle in the cache - $key = array_search(false, $this->multiOwned, true); - if (false !== $key) { - $this->multiOwned[$key] = true; - return $this->multiHandles[$key]; - } - - // Add a new handle - $handle = curl_multi_init(); - $id = (int) $handle; - $this->multiHandles[$id] = $handle; - $this->multiOwned[$id] = true; - - return $handle; - } - - /** - * Releases a curl_multi handle back into the cache and removes excess cache - * - * @param resource $handle Curl multi handle to remove - */ - private function releaseMultiHandle($handle) - { - $id = (int) $handle; - - if (count($this->multiHandles) <= 3) { - $this->multiOwned[$id] = false; - } else { - // Prune excessive handles - curl_multi_close($this->multiHandles[$id]); - unset($this->multiHandles[$id], $this->multiOwned[$id]); - } - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Adapter/Curl/RequestMediator.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Adapter/Curl/RequestMediator.php deleted file mode 100644 index 19cbcfd090cbf9211f6d393f4d8e8ced5d264eb7..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Adapter/Curl/RequestMediator.php +++ /dev/null @@ -1,130 +0,0 @@ -transaction = $transaction; - $this->messageFactory = $messageFactory; - } - - /** - * Set the body that will hold the response body - * - * @param StreamInterface $body Response body - */ - public function setResponseBody(StreamInterface $body = null) - { - $this->body = $body; - } - - /** - * Receive a response header from curl - * - * @param resource $curl Curl handle - * @param string $header Received header - * - * @return int - */ - public function receiveResponseHeader($curl, $header) - { - static $normalize = ["\r", "\n"]; - $length = strlen($header); - $header = str_replace($normalize, '', $header); - - if (strpos($header, 'HTTP/') === 0) { - $startLine = explode(' ', $header, 3); - // Only download the body to a target body when a successful - // response is received. - if ($startLine[1][0] != '2') { - $this->body = null; - } - $this->statusCode = $startLine[1]; - $this->reasonPhrase = isset($startLine[2]) ? $startLine[2] : null; - $this->protocolVersion = substr($startLine[0], -3); - $this->headers = []; - } elseif ($pos = strpos($header, ':')) { - $this->headers[substr($header, 0, $pos)][] = substr($header, $pos + 1); - } elseif ($header == '' && $this->statusCode >= 200) { - $response = $this->messageFactory->createResponse( - $this->statusCode, - $this->headers, - $this->body, - [ - 'protocol_version' => $this->protocolVersion, - 'reason_phrase' => $this->reasonPhrase - ] - ); - $this->headers = $this->body = null; - $this->transaction->setResponse($response); - // Allows events to react before downloading any of the body - RequestEvents::emitHeaders($this->transaction); - } - - return $length; - } - - /** - * Write data to the response body of a request - * - * @param resource $curl - * @param string $write - * - * @return int - */ - public function writeResponseBody($curl, $write) - { - if (!($response = $this->transaction->getResponse())) { - return 0; - } - - // Add a default body on the response if one was not found - if (!($body = $response->getBody())) { - $body = new Stream(fopen('php://temp', 'r+')); - $response->setBody($body); - } - - return $body->write($write); - } - - /** - * Read data from the request body and send it to curl - * - * @param resource $ch Curl handle - * @param resource $fd File descriptor - * @param int $length Amount of data to read - * - * @return string - */ - public function readRequestBody($ch, $fd, $length) - { - return (string) $this->transaction->getRequest()->getBody()->read($length); - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Adapter/FakeParallelAdapter.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Adapter/FakeParallelAdapter.php deleted file mode 100644 index 302656837f1956a9181780d9ea319e753fe8eb30..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Adapter/FakeParallelAdapter.php +++ /dev/null @@ -1,34 +0,0 @@ -adapter = $adapter; - } - - public function sendAll(\Iterator $transactions, $parallel) - { - foreach ($transactions as $transaction) { - try { - $this->adapter->send($transaction); - } catch (RequestException $e) { - // no op for batch transaction - } - } - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Adapter/MockAdapter.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Adapter/MockAdapter.php deleted file mode 100644 index 3e8020e69842da49d331b8b5c68396b681b55fa7..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Adapter/MockAdapter.php +++ /dev/null @@ -1,60 +0,0 @@ -setResponse($response); - } - - /** - * Set the response that will be served by the adapter - * - * @param ResponseInterface|callable $response Response to serve or - * function to invoke that handles a transaction - */ - public function setResponse($response) - { - $this->response = $response; - } - - public function send(TransactionInterface $transaction) - { - RequestEvents::emitBefore($transaction); - if (!$transaction->getResponse()) { - - // Read the request body if it is present - if ($transaction->getRequest()->getBody()) { - $transaction->getRequest()->getBody()->__toString(); - } - - $response = is_callable($this->response) - ? call_user_func($this->response, $transaction) - : $this->response; - if (!$response instanceof ResponseInterface) { - throw new \RuntimeException('Invalid mocked response'); - } - - $transaction->setResponse($response); - RequestEvents::emitHeaders($transaction); - RequestEvents::emitComplete($transaction); - } - - return $transaction->getResponse(); - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Adapter/ParallelAdapterInterface.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Adapter/ParallelAdapterInterface.php deleted file mode 100644 index 79a25b7e0dc3a6591f1a15d080f8e489489ab689..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Adapter/ParallelAdapterInterface.php +++ /dev/null @@ -1,23 +0,0 @@ -messageFactory = $messageFactory; - } - - public function send(TransactionInterface $transaction) - { - // HTTP/1.1 streams using the PHP stream wrapper require a - // Connection: close header. Setting here so that it is added before - // emitting the request.before_send event. - $request = $transaction->getRequest(); - if ($request->getProtocolVersion() == '1.1' && - !$request->hasHeader('Connection') - ) { - $transaction->getRequest()->setHeader('Connection', 'close'); - } - - RequestEvents::emitBefore($transaction); - if (!$transaction->getResponse()) { - $this->createResponse($transaction); - RequestEvents::emitComplete($transaction); - } - - return $transaction->getResponse(); - } - - private function createResponse(TransactionInterface $transaction) - { - $request = $transaction->getRequest(); - $stream = $this->createStream($request, $http_response_header); - - if (!$request->getConfig()['stream']) { - $stream = $this->getSaveToBody($request, $stream); - } - - // Track the response headers of the request - $this->createResponseObject($http_response_header, $transaction, $stream); - } - - /** - * Drain the steam into the destination stream - */ - private function getSaveToBody(RequestInterface $request, $stream) - { - if ($saveTo = $request->getConfig()['save_to']) { - // Stream the response into the destination stream - $saveTo = is_string($saveTo) - ? Stream\create(fopen($saveTo, 'r+')) - : Stream\create($saveTo); - } else { - // Stream into the default temp stream - $saveTo = Stream\create(); - } - - while (!feof($stream)) { - $saveTo->write(fread($stream, 8096)); - } - - fclose($stream); - $saveTo->seek(0); - - return $saveTo; - } - - private function createResponseObject( - array $headers, - TransactionInterface $transaction, - $stream - ) { - $parts = explode(' ', array_shift($headers), 3); - $options = ['protocol_version' => substr($parts[0], -3)]; - if (isset($parts[2])) { - $options['reason_phrase'] = $parts[2]; - } - - // Set the size on the stream if it was returned in the response - $responseHeaders = []; - foreach ($headers as $header) { - $headerParts = explode(':', $header, 2); - $responseHeaders[$headerParts[0]] = isset($headerParts[1]) - ? $headerParts[1] - : ''; - } - - $response = $this->messageFactory->createResponse( - $parts[1], - $responseHeaders, - $stream, - $options - ); - - $transaction->setResponse($response); - RequestEvents::emitHeaders($transaction); - - return $response; - } - - /** - * Create a resource and check to ensure it was created successfully - * - * @param callable $callback Callable that returns stream resource - * @param RequestInterface $request Request used when throwing exceptions - * @param array $options Options used when throwing exceptions - * - * @return resource - * @throws RequestException on error - */ - private function createResource(callable $callback, RequestInterface $request, $options) - { - // Turn off error reporting while we try to initiate the request - $level = error_reporting(0); - $resource = call_user_func($callback); - error_reporting($level); - - // If the resource could not be created, then grab the last error and - // throw an exception. - if (!is_resource($resource)) { - $message = 'Error creating resource. [url] ' . $request->getUrl() . ' '; - if (isset($options['http']['proxy'])) { - $message .= "[proxy] {$options['http']['proxy']} "; - } - foreach (error_get_last() as $key => $value) { - $message .= "[{$key}] {$value} "; - } - throw new RequestException(trim($message), $request); - } - - return $resource; - } - - /** - * Create the stream for the request with the context options. - * - * @param RequestInterface $request Request being sent - * @param mixed $http_response_header Populated by stream wrapper - * - * @return resource - */ - private function createStream( - RequestInterface $request, - &$http_response_header - ) { - static $methods; - if (!$methods) { - $methods = array_flip(get_class_methods(__CLASS__)); - } - - $params = []; - $options = $this->getDefaultOptions($request); - foreach ($request->getConfig()->toArray() as $key => $value) { - $method = "add_{$key}"; - if (isset($methods[$method])) { - $this->{$method}($request, $options, $value, $params); - } - } - - $this->applyCustomOptions($request, $options); - $context = $this->createStreamContext($request, $options, $params); - - return $this->createStreamResource( - $request, - $options, - $context, - $http_response_header - ); - } - - private function getDefaultOptions(RequestInterface $request) - { - $headers = ''; - foreach ($request->getHeaders() as $name => $values) { - $headers .= $name . ': ' . implode(', ', $values) . "\r\n"; - } - - return [ - 'http' => [ - 'method' => $request->getMethod(), - 'header' => trim($headers), - 'protocol_version' => $request->getProtocolVersion(), - 'ignore_errors' => true, - 'follow_location' => 0, - 'content' => (string) $request->getBody() - ] - ]; - } - - private function add_proxy(RequestInterface $request, &$options, $value, &$params) - { - if (!is_array($value)) { - $options['http']['proxy'] = $value; - $options['http']['request_fulluri'] = true; - } else { - $scheme = $request->getScheme(); - if (isset($value[$scheme])) { - $options['http']['proxy'] = $value[$scheme]; - $options['http']['request_fulluri'] = true; - } - } - } - - private function add_timeout(RequestInterface $request, &$options, $value, &$params) - { - $options['http']['timeout'] = $value; - } - - private function add_verify(RequestInterface $request, &$options, $value, &$params) - { - if ($value === true || is_string($value)) { - $options['http']['verify_peer'] = true; - if ($value !== true) { - if (!file_exists($value)) { - throw new \RuntimeException("SSL certificate authority file not found: {$value}"); - } - $options['http']['allow_self_signed'] = true; - $options['http']['cafile'] = $value; - } - } elseif ($value === false) { - $options['http']['verify_peer'] = false; - } - } - - private function add_cert(RequestInterface $request, &$options, $value, &$params) - { - if (is_array($value)) { - $options['http']['passphrase'] = $value[1]; - $value = $value[0]; - } - - if (!file_exists($value)) { - throw new \RuntimeException("SSL certificate not found: {$value}"); - } - - $options['http']['local_cert'] = $value; - } - - private function add_debug(RequestInterface $request, &$options, $value, &$params) - { - static $map = [ - STREAM_NOTIFY_CONNECT => 'CONNECT', - STREAM_NOTIFY_AUTH_REQUIRED => 'AUTH_REQUIRED', - STREAM_NOTIFY_AUTH_RESULT => 'AUTH_RESULT', - STREAM_NOTIFY_MIME_TYPE_IS => 'MIME_TYPE_IS', - STREAM_NOTIFY_FILE_SIZE_IS => 'FILE_SIZE_IS', - STREAM_NOTIFY_REDIRECTED => 'REDIRECTED', - STREAM_NOTIFY_PROGRESS => 'PROGRESS', - STREAM_NOTIFY_FAILURE => 'FAILURE', - STREAM_NOTIFY_COMPLETED => 'COMPLETED', - STREAM_NOTIFY_RESOLVE => 'RESOLVE' - ]; - - static $args = ['severity', 'message', 'message_code', - 'bytes_transferred', 'bytes_max']; - - if (!is_resource($value)) { - $value = fopen('php://output', 'w'); - } - - $params['notification'] = function () use ($request, $value, $map, $args) { - $passed = func_get_args(); - $code = array_shift($passed); - fprintf($value, '<%s> [%s] ', $request->getUrl(), $map[$code]); - foreach (array_filter($passed) as $i => $v) { - fwrite($value, $args[$i] . ': "' . $v . '" '); - } - fwrite($value, "\n"); - }; - } - - private function applyCustomOptions( - RequestInterface $request, - array &$options - ) { - // Overwrite any generated options with custom options - if ($custom = $request->getConfig()['stream_context']) { - if (!is_array($custom)) { - throw new AdapterException('stream_context must be an array'); - } - $options = array_replace_recursive($options, $custom); - } - } - - private function createStreamContext( - RequestInterface $request, - array $options, - array $params - ) { - return $this->createResource(function () use ( - $request, - $options, - $params - ) { - return stream_context_create($options, $params); - }, $request, $options); - } - - private function createStreamResource( - RequestInterface $request, - array $options, - $context, - &$http_response_header - ) { - $url = $request->getUrl(); - // Add automatic gzip decompression - if (strpos($request->getHeader('Accept-Encoding'), 'gzip') !== false) { - $url = 'compress.zlib://' . $url; - } - - return $this->createResource(function () use ( - $url, - &$http_response_header, - $context - ) { - if (false === strpos($url, 'http')) { - trigger_error("URL is invalid: {$url}", E_USER_WARNING); - return null; - } - return fopen($url, 'r', null, $context); - }, $request, $options); - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Adapter/StreamingProxyAdapter.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Adapter/StreamingProxyAdapter.php deleted file mode 100644 index 128eb1d1e12c5a31dadf64c77f1cd6ed4fe66c3b..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Adapter/StreamingProxyAdapter.php +++ /dev/null @@ -1,36 +0,0 @@ -defaultAdapter = $defaultAdapter; - $this->streamingAdapter = $streamingAdapter; - } - - public function send(TransactionInterface $transaction) - { - return $transaction->getRequest()->getConfig()['stream'] - ? $this->streamingAdapter->send($transaction) - : $this->defaultAdapter->send($transaction); - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Adapter/Transaction.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Adapter/Transaction.php deleted file mode 100644 index 74bb6b44234e0564c20fe2f557f7ffb0f182f3cd..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Adapter/Transaction.php +++ /dev/null @@ -1,49 +0,0 @@ -client = $client; - $this->request = $request; - } - - public function getRequest() - { - return $this->request; - } - - public function getResponse() - { - return $this->response; - } - - public function setResponse(ResponseInterface $response) - { - $this->response = $response; - } - - public function getClient() - { - return $this->client; - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Adapter/TransactionInterface.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Adapter/TransactionInterface.php deleted file mode 100644 index b9bf50cbaccb276b488d2699f5e510e1b154e06a..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Adapter/TransactionInterface.php +++ /dev/null @@ -1,35 +0,0 @@ -client = $client; - $this->eventListeners = $this->prepareListeners( - $options, - ['before', 'complete', 'error'] - ); - if ($source instanceof \Iterator) { - $this->source = $source; - } elseif (is_array($source)) { - $this->source = new \ArrayIterator($source); - } else { - throw new \InvalidArgumentException('Expected an Iterator or array'); - } - } - - public function current() - { - $request = $this->source->current(); - if (!$request instanceof RequestInterface) { - throw new \RuntimeException('All must implement RequestInterface'); - } - - $this->attachListeners($request, $this->eventListeners); - - return new Transaction($this->client, $request); - } - - public function next() - { - $this->source->next(); - } - - public function key() - { - return $this->source->key(); - } - - public function valid() - { - return $this->source->valid(); - } - - public function rewind() {} -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Client.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Client.php deleted file mode 100644 index 898157e1809aec499451c0b8ba50a08dbd7906ff..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Client.php +++ /dev/null @@ -1,364 +0,0 @@ - [ - * 'http://www.foo.com/{version}/', - * ['version' => '123'] - * ], - * 'defaults' => [ - * 'timeout' => 10, - * 'allow_redirects' => false, - * 'proxy' => '192.168.16.1:10' - * ] - * ]); - * - * @param array $config Client configuration settings - * - base_url: Base URL of the client that is merged into relative URLs. - * Can be a string or an array that contains a URI template followed - * by an associative array of expansion variables to inject into the - * URI template. - * - adapter: Adapter used to transfer requests - * - parallel_adapter: Adapter used to transfer requests in parallel - * - message_factory: Factory used to create request and response object - * - defaults: Default request options to apply to each request - * - emitter: Event emitter used for request events - */ - public function __construct(array $config = []) - { - $this->configureBaseUrl($config); - $this->configureDefaults($config); - $this->configureAdapter($config); - if (isset($config['emitter'])) { - $this->emitter = $config['emitter']; - } - } - - /** - * Get the default User-Agent string to use with Guzzle - * - * @return string - */ - public static function getDefaultUserAgent() - { - static $defaultAgent = ''; - if (!$defaultAgent) { - $defaultAgent = 'Guzzle/' . self::VERSION; - if (extension_loaded('curl')) { - $defaultAgent .= ' curl/' . curl_version()['version']; - } - $defaultAgent .= ' PHP/' . PHP_VERSION; - } - - return $defaultAgent; - } - - public function __call($name, $arguments) - { - return \GuzzleHttp\deprecation_proxy( - $this, - $name, - $arguments, - ['getEventDispatcher' => 'getEmitter'] - ); - } - - public function getDefaultOption($keyOrPath = null) - { - return $keyOrPath === null - ? $this->defaults - : \GuzzleHttp\get_path($this->defaults, $keyOrPath); - } - - public function setDefaultOption($keyOrPath, $value) - { - \GuzzleHttp\set_path($this->defaults, $keyOrPath, $value); - } - - public function getBaseUrl() - { - return (string) $this->baseUrl; - } - - public function createRequest($method, $url = null, array $options = []) - { - // Merge in default options - $options = array_replace_recursive($this->defaults, $options); - - // Use a clone of the client's emitter - $options['config']['emitter'] = clone $this->getEmitter(); - - $request = $this->messageFactory->createRequest( - $method, - $url ? (string) $this->buildUrl($url) : (string) $this->baseUrl, - $options - ); - - return $request; - } - - public function get($url = null, $options = []) - { - return $this->send($this->createRequest('GET', $url, $options)); - } - - public function head($url = null, array $options = []) - { - return $this->send($this->createRequest('HEAD', $url, $options)); - } - - public function delete($url = null, array $options = []) - { - return $this->send($this->createRequest('DELETE', $url, $options)); - } - - public function put($url = null, array $options = []) - { - return $this->send($this->createRequest('PUT', $url, $options)); - } - - public function patch($url = null, array $options = []) - { - return $this->send($this->createRequest('PATCH', $url, $options)); - } - - public function post($url = null, array $options = []) - { - return $this->send($this->createRequest('POST', $url, $options)); - } - - public function options($url = null, array $options = []) - { - return $this->send($this->createRequest('OPTIONS', $url, $options)); - } - - public function send(RequestInterface $request) - { - $transaction = new Transaction($this, $request); - try { - if ($response = $this->adapter->send($transaction)) { - return $response; - } - throw new \LogicException('No response was associated with the transaction'); - } catch (RequestException $e) { - throw $e; - } catch (\Exception $e) { - // Wrap exceptions in a RequestException to adhere to the interface - throw new RequestException($e->getMessage(), $request, null, $e); - } - } - - public function sendAll($requests, array $options = []) - { - if (!($requests instanceof TransactionIterator)) { - $requests = new TransactionIterator($requests, $this, $options); - } - - $this->parallelAdapter->sendAll( - $requests, - isset($options['parallel']) - ? $options['parallel'] - : self::DEFAULT_CONCURRENCY - ); - } - - /** - * Get an array of default options to apply to the client - * - * @return array - */ - protected function getDefaultOptions() - { - $settings = [ - 'allow_redirects' => true, - 'exceptions' => true, - 'verify' => __DIR__ . '/cacert.pem' - ]; - - // Use the bundled cacert if it is a regular file, or set to true if - // using a phar file (because curL and the stream wrapper can't read - // cacerts from the phar stream wrapper). Favor the ini setting over - // the system's cacert. - if (substr(__FILE__, 0, 7) == 'phar://') { - $settings['verify'] = ini_get('openssl.cafile') ?: true; - } - - // Use the standard Linux HTTP_PROXY and HTTPS_PROXY if set - if (isset($_SERVER['HTTP_PROXY'])) { - $settings['proxy']['http'] = $_SERVER['HTTP_PROXY']; - } - - if (isset($_SERVER['HTTPS_PROXY'])) { - $settings['proxy']['https'] = $_SERVER['HTTPS_PROXY']; - } - - return $settings; - } - - /** - * Expand a URI template and inherit from the base URL if it's relative - * - * @param string|array $url URL or URI template to expand - * - * @return string - */ - private function buildUrl($url) - { - if (!is_array($url)) { - if (strpos($url, '://')) { - return (string) $url; - } - return (string) $this->baseUrl->combine($url); - } elseif (strpos($url[0], '://')) { - return \GuzzleHttp\uri_template($url[0], $url[1]); - } - - return (string) $this->baseUrl->combine( - \GuzzleHttp\uri_template($url[0], $url[1]) - ); - } - - /** - * Get a default parallel adapter to use based on the environment - * - * @return ParallelAdapterInterface - */ - private function getDefaultParallelAdapter() - { - return extension_loaded('curl') - ? new MultiAdapter($this->messageFactory) - : new FakeParallelAdapter($this->adapter); - } - - /** - * Create a default adapter to use based on the environment - * @throws \RuntimeException - */ - private function getDefaultAdapter() - { - if (extension_loaded('curl')) { - $this->parallelAdapter = new MultiAdapter($this->messageFactory); - $this->adapter = function_exists('curl_reset') - ? new CurlAdapter($this->messageFactory) - : $this->parallelAdapter; - if (ini_get('allow_url_fopen')) { - $this->adapter = new StreamingProxyAdapter( - $this->adapter, - new StreamAdapter($this->messageFactory) - ); - } - } elseif (ini_get('allow_url_fopen')) { - $this->adapter = new StreamAdapter($this->messageFactory); - } else { - throw new \RuntimeException('Guzzle requires cURL, the ' - . 'allow_url_fopen ini setting, or a custom HTTP adapter.'); - } - } - - private function configureBaseUrl(&$config) - { - if (!isset($config['base_url'])) { - $this->baseUrl = new Url('', ''); - } elseif (is_array($config['base_url'])) { - $this->baseUrl = Url::fromString( - \GuzzleHttp\uri_template( - $config['base_url'][0], - $config['base_url'][1] - ) - ); - $config['base_url'] = (string) $this->baseUrl; - } else { - $this->baseUrl = Url::fromString($config['base_url']); - } - } - - private function configureDefaults($config) - { - if (!isset($config['defaults'])) { - $this->defaults = $this->getDefaultOptions(); - } else { - $this->defaults = array_replace( - $this->getDefaultOptions(), - $config['defaults'] - ); - } - - // Add the default user-agent header - if (!isset($this->defaults['headers'])) { - $this->defaults['headers'] = [ - 'User-Agent' => static::getDefaultUserAgent() - ]; - } elseif (!isset(array_change_key_case($this->defaults['headers'])['user-agent'])) { - // Add the User-Agent header if one was not already set - $this->defaults['headers']['User-Agent'] = static::getDefaultUserAgent(); - } - } - - private function configureAdapter(&$config) - { - if (isset($config['message_factory'])) { - $this->messageFactory = $config['message_factory']; - } else { - $this->messageFactory = new MessageFactory(); - } - if (isset($config['adapter'])) { - $this->adapter = $config['adapter']; - } else { - $this->getDefaultAdapter(); - } - // If no parallel adapter was explicitly provided and one was not - // defaulted when creating the default adapter, then create one now. - if (isset($config['parallel_adapter'])) { - $this->parallelAdapter = $config['parallel_adapter']; - } elseif (!$this->parallelAdapter) { - $this->parallelAdapter = $this->getDefaultParallelAdapter(); - } - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/ClientInterface.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/ClientInterface.php deleted file mode 100644 index b0e4cba7f93cec9ed8bec64a6bba4eb38edf96a6..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/ClientInterface.php +++ /dev/null @@ -1,179 +0,0 @@ -data = $data; - } - - /** - * Create a new collection from an array, validate the keys, and add default - * values where missing - * - * @param array $config Configuration values to apply. - * @param array $defaults Default parameters - * @param array $required Required parameter names - * - * @return self - * @throws \InvalidArgumentException if a parameter is missing - */ - public static function fromConfig( - array $config = [], - array $defaults = [], - array $required = [] - ) { - $data = $config + $defaults; - - if ($missing = array_diff($required, array_keys($data))) { - throw new \InvalidArgumentException( - 'Config is missing the following keys: ' . - implode(', ', $missing)); - } - - return new self($data); - } - - /** - * Removes all key value pairs - * - * @return Collection - */ - public function clear() - { - $this->data = []; - - return $this; - } - - /** - * Get a specific key value. - * - * @param string $key Key to retrieve. - * - * @return mixed|null Value of the key or NULL - */ - public function get($key) - { - return isset($this->data[$key]) ? $this->data[$key] : null; - } - - /** - * Set a key value pair - * - * @param string $key Key to set - * @param mixed $value Value to set - * - * @return Collection Returns a reference to the object - */ - public function set($key, $value) - { - $this->data[$key] = $value; - - return $this; - } - - /** - * Add a value to a key. If a key of the same name has already been added, - * the key value will be converted into an array and the new value will be - * pushed to the end of the array. - * - * @param string $key Key to add - * @param mixed $value Value to add to the key - * - * @return Collection Returns a reference to the object. - */ - public function add($key, $value) - { - if (!array_key_exists($key, $this->data)) { - $this->data[$key] = $value; - } elseif (is_array($this->data[$key])) { - $this->data[$key][] = $value; - } else { - $this->data[$key] = array($this->data[$key], $value); - } - - return $this; - } - - /** - * Remove a specific key value pair - * - * @param string $key A key to remove - * - * @return Collection - */ - public function remove($key) - { - unset($this->data[$key]); - - return $this; - } - - /** - * Get all keys in the collection - * - * @return array - */ - public function getKeys() - { - return array_keys($this->data); - } - - /** - * Returns whether or not the specified key is present. - * - * @param string $key The key for which to check the existence. - * - * @return bool - */ - public function hasKey($key) - { - return array_key_exists($key, $this->data); - } - - /** - * Checks if any keys contains a certain value - * - * @param string $value Value to search for - * - * @return mixed Returns the key if the value was found FALSE if the value - * was not found. - */ - public function hasValue($value) - { - return array_search($value, $this->data, true); - } - - /** - * Replace the data of the object with the value of an array - * - * @param array $data Associative array of data - * - * @return Collection Returns a reference to the object - */ - public function replace(array $data) - { - $this->data = $data; - - return $this; - } - - /** - * Add and merge in a Collection or array of key value pair data. - * - * @param Collection|array $data Associative array of key value pair data - * - * @return Collection Returns a reference to the object. - */ - public function merge($data) - { - foreach ($data as $key => $value) { - $this->add($key, $value); - } - - return $this; - } - - /** - * Over write key value pairs in this collection with all of the data from - * an array or collection. - * - * @param array|\Traversable $data Values to override over this config - * - * @return self - */ - public function overwriteWith($data) - { - if (is_array($data)) { - $this->data = $data + $this->data; - } elseif ($data instanceof Collection) { - $this->data = $data->toArray() + $this->data; - } else { - foreach ($data as $key => $value) { - $this->data[$key] = $value; - } - } - - return $this; - } - - /** - * Returns a Collection containing all the elements of the collection after - * applying the callback function to each one. - * - * The callable should accept three arguments: - * - (string) $key - * - (string) $value - * - (array) $context - * - * The callable must return a the altered or unaltered value. - * - * @param callable $closure Map function to apply - * @param array $context Context to pass to the callable - * - * @return Collection - */ - public function map(callable $closure, array $context = []) - { - $collection = new static(); - foreach ($this as $key => $value) { - $collection[$key] = $closure($key, $value, $context); - } - - return $collection; - } - - /** - * Iterates over each key value pair in the collection passing them to the - * callable. If the callable returns true, the current value from input is - * returned into the result Collection. - * - * The callable must accept two arguments: - * - (string) $key - * - (string) $value - * - * @param callable $closure Evaluation function - * - * @return Collection - */ - public function filter(callable $closure) - { - $collection = new static(); - foreach ($this->data as $key => $value) { - if ($closure($key, $value)) { - $collection[$key] = $value; - } - } - - return $collection; - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Cookie/CookieJar.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Cookie/CookieJar.php deleted file mode 100644 index 4134857827c5f00aff84f7136b1e5129feaf4cc8..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Cookie/CookieJar.php +++ /dev/null @@ -1,249 +0,0 @@ -strictMode = $strictMode; - - foreach ($cookieArray as $cookie) { - if (!($cookieArray instanceof SetCookie)) { - $cookie = new SetCookie($cookie); - } - $this->setCookie($cookie); - } - } - - /** - * Create a new Cookie jar from an associative array and domain. - * - * @param array $cookies Cookies to create the jar from - * @param string $domain Domain to set the cookies to - * - * @return self - */ - public static function fromArray(array $cookies, $domain) - { - $cookieJar = new self(); - foreach ($cookies as $name => $value) { - $cookieJar->setCookie(new SetCookie([ - 'Domain' => $domain, - 'Name' => $name, - 'Value' => $value, - 'Discard' => true - ])); - } - - return $cookieJar; - } - - /** - * Quote the cookie value if it is not already quoted and it contains - * problematic characters. - * - * @param string $value Value that may or may not need to be quoted - * - * @return string - */ - public static function getCookieValue($value) - { - if (substr($value, 0, 1) !== '"' && - substr($value, -1, 1) !== '"' && - strpbrk($value, ';,') - ) { - $value = '"' . $value . '"'; - } - - return $value; - } - - public function toArray() - { - return array_map(function (SetCookie $cookie) { - return $cookie->toArray(); - }, $this->getIterator()->getArrayCopy()); - } - - public function clear($domain = null, $path = null, $name = null) - { - if (!$domain) { - $this->cookies = []; - return; - } elseif (!$path) { - $this->cookies = array_filter( - $this->cookies, - function (SetCookie $cookie) use ($path, $domain) { - return !$cookie->matchesDomain($domain); - } - ); - } elseif (!$name) { - $this->cookies = array_filter( - $this->cookies, - function (SetCookie $cookie) use ($path, $domain) { - return !($cookie->matchesPath($path) && - $cookie->matchesDomain($domain)); - } - ); - } else { - $this->cookies = array_filter( - $this->cookies, - function (SetCookie $cookie) use ($path, $domain, $name) { - return !($cookie->getName() == $name && - $cookie->matchesPath($path) && - $cookie->matchesDomain($domain)); - } - ); - } - } - - public function clearSessionCookies() - { - $this->cookies = array_filter( - $this->cookies, - function (SetCookie $cookie) { - return !$cookie->getDiscard() && $cookie->getExpires(); - } - ); - } - - public function setCookie(SetCookie $cookie) - { - // Only allow cookies with set and valid domain, name, value - $result = $cookie->validate(); - if ($result !== true) { - if ($this->strictMode) { - throw new \RuntimeException('Invalid cookie: ' . $result); - } else { - $this->removeCookieIfEmpty($cookie); - return false; - } - } - - // Resolve conflicts with previously set cookies - foreach ($this->cookies as $i => $c) { - - // Two cookies are identical, when their path, and domain are - // identical. - if ($c->getPath() != $cookie->getPath() || - $c->getDomain() != $cookie->getDomain() || - $c->getName() != $cookie->getName() - ) { - continue; - } - - // The previously set cookie is a discard cookie and this one is - // not so allow the new cookie to be set - if (!$cookie->getDiscard() && $c->getDiscard()) { - unset($this->cookies[$i]); - continue; - } - - // If the new cookie's expiration is further into the future, then - // replace the old cookie - if ($cookie->getExpires() > $c->getExpires()) { - unset($this->cookies[$i]); - continue; - } - - // If the value has changed, we better change it - if ($cookie->getValue() !== $c->getValue()) { - unset($this->cookies[$i]); - continue; - } - - // The cookie exists, so no need to continue - return false; - } - - $this->cookies[] = $cookie; - - return true; - } - - public function count() - { - return count($this->cookies); - } - - public function getIterator() - { - return new \ArrayIterator(array_values($this->cookies)); - } - - public function extractCookies( - RequestInterface $request, - ResponseInterface $response - ) { - if ($cookieHeader = $response->getHeader('Set-Cookie', true)) { - foreach ($cookieHeader as $cookie) { - $sc = SetCookie::fromString($cookie); - if (!$sc->getDomain()) { - $sc->setDomain($request->getHost()); - } - $this->setCookie($sc); - } - } - } - - public function addCookieHeader(RequestInterface $request) - { - $values = []; - $scheme = $request->getScheme(); - $host = $request->getHost(); - $path = $request->getPath(); - - foreach ($this->cookies as $cookie) { - if ($cookie->matchesPath($path) && - $cookie->matchesDomain($host) && - !$cookie->isExpired() && - (!$cookie->getSecure() || $scheme == 'https') - ) { - $values[] = $cookie->getName() . '=' - . self::getCookieValue($cookie->getValue()); - } - } - - if ($values) { - $request->setHeader('Cookie', implode(';', $values)); - } - } - - /** - * If a cookie already exists and the server asks to set it again with a - * null value, the cookie must be deleted. - * - * @param SetCookie $cookie - */ - private function removeCookieIfEmpty(SetCookie $cookie) - { - $cookieValue = $cookie->getValue(); - if ($cookieValue === null || $cookieValue === '') { - $this->clear( - $cookie->getDomain(), - $cookie->getPath(), - $cookie->getName() - ); - } - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Cookie/CookieJarInterface.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Cookie/CookieJarInterface.php deleted file mode 100644 index 6cafce8cc3b99151a74c212da1006389674b70e7..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Cookie/CookieJarInterface.php +++ /dev/null @@ -1,76 +0,0 @@ -filename = $cookieFile; - - if (file_exists($cookieFile)) { - $this->load($cookieFile); - } - } - - /** - * Saves the file when shutting down - */ - public function __destruct() - { - $this->save($this->filename); - } - - /** - * Saves the cookies to a file. - * - * @param string $filename File to save - * @throws \RuntimeException if the file cannot be found or created - */ - public function save($filename) - { - $json = []; - foreach ($this as $cookie) { - if ($cookie->getExpires() && !$cookie->getDiscard()) { - $json[] = $cookie->toArray(); - } - } - - if (false === file_put_contents($filename, json_encode($json))) { - // @codeCoverageIgnoreStart - throw new \RuntimeException("Unable to save file {$filename}"); - // @codeCoverageIgnoreEnd - } - } - - /** - * Load cookies from a JSON formatted file. - * - * Old cookies are kept unless overwritten by newly loaded ones. - * - * @param string $filename Cookie file to load. - * @throws \RuntimeException if the file cannot be loaded. - */ - public function load($filename) - { - $json = file_get_contents($filename); - if (false === $json) { - // @codeCoverageIgnoreStart - throw new \RuntimeException("Unable to load file {$filename}"); - // @codeCoverageIgnoreEnd - } - - $data = \GuzzleHttp\json_decode($json, true); - if (is_array($data)) { - foreach (\GuzzleHttp\json_decode($json, true) as $cookie) { - $this->setCookie(new SetCookie($cookie)); - } - } elseif (strlen($data)) { - throw new \RuntimeException("Invalid cookie file: {$filename}"); - } - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Cookie/SessionCookieJar.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Cookie/SessionCookieJar.php deleted file mode 100644 index 2f708d74ed4e70114eabfea86b62ac4c8fa486cc..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Cookie/SessionCookieJar.php +++ /dev/null @@ -1,65 +0,0 @@ -sessionKey = $sessionKey; - $this->load(); - } - - /** - * Saves cookies to session when shutting down - */ - public function __destruct() - { - $this->save(); - } - - /** - * Save cookies to the client session - */ - public function save() - { - $json = []; - foreach ($this as $cookie) { - if ($cookie->getExpires() && !$cookie->getDiscard()) { - $json[] = $cookie->toArray(); - } - } - - $_SESSION[$this->sessionKey] = json_encode($json); - } - - /** - * Load the contents of the client session into the data array - */ - protected function load() - { - $cookieJar = isset($_SESSION[$this->sessionKey]) - ? $_SESSION[$this->sessionKey] - : null; - - $data = \GuzzleHttp\json_decode($cookieJar, true); - if (is_array($data)) { - foreach ($data as $cookie) { - $this->setCookie(new SetCookie($cookie)); - } - } elseif (strlen($data)) { - throw new \RuntimeException("Invalid cookie data"); - } - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Cookie/SetCookie.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Cookie/SetCookie.php deleted file mode 100644 index 76f6f8d15c989c7617def57159b100c4161bfe2a..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Cookie/SetCookie.php +++ /dev/null @@ -1,410 +0,0 @@ - null, - 'Value' => null, - 'Domain' => null, - 'Path' => '/', - 'Max-Age' => null, - 'Expires' => null, - 'Secure' => false, - 'Discard' => false, - 'HttpOnly' => false - ]; - - /** @var array Cookie data */ - private $data; - - /** - * Create a new SetCookie object from a string - * - * @param string $cookie Set-Cookie header string - * - * @return self - */ - public static function fromString($cookie) - { - // Create the default return array - $data = self::$defaults; - // Explode the cookie string using a series of semicolons - $pieces = array_filter(array_map('trim', explode(';', $cookie))); - // The name of the cookie (first kvp) must include an equal sign. - if (empty($pieces) || !strpos($pieces[0], '=')) { - return new self($data); - } - - // Add the cookie pieces into the parsed data array - foreach ($pieces as $part) { - - $cookieParts = explode('=', $part, 2); - $key = trim($cookieParts[0]); - $value = isset($cookieParts[1]) - ? trim($cookieParts[1], " \n\r\t\0\x0B\"") - : true; - - // Only check for non-cookies when cookies have been found - if (empty($data['Name'])) { - $data['Name'] = $key; - $data['Value'] = $value; - } else { - foreach (array_keys(self::$defaults) as $search) { - if (!strcasecmp($search, $key)) { - $data[$search] = $value; - continue 2; - } - } - $data[$key] = $value; - } - } - - return new self($data); - } - - /** - * @param array $data Array of cookie data provided by a Cookie parser - */ - public function __construct(array $data = []) - { - $this->data = array_replace(self::$defaults, $data); - // Extract the Expires value and turn it into a UNIX timestamp if needed - if (!$this->getExpires() && $this->getMaxAge()) { - // Calculate the Expires date - $this->setExpires(time() + $this->getMaxAge()); - } elseif ($this->getExpires() && !is_numeric($this->getExpires())) { - $this->setExpires($this->getExpires()); - } - } - - public function __toString() - { - $str = $this->data['Name'] . '=' . $this->data['Value'] . '; '; - foreach ($this->data as $k => $v) { - if ($k != 'Name' && $k != 'Value'&& $v !== null && $v !== false) { - if ($k == 'Expires') { - $str .= 'Expires=' . gmdate('D, d M Y H:i:s \G\M\T', $v) . '; '; - } else { - $str .= ($v === true ? $k : "{$k}={$v}") . '; '; - } - } - } - - return rtrim($str, '; '); - } - - public function toArray() - { - return $this->data; - } - - /** - * Get the cookie name - * - * @return string - */ - public function getName() - { - return $this->data['Name']; - } - - /** - * Set the cookie name - * - * @param string $name Cookie name - * - * @return self - */ - public function setName($name) - { - $this->data['Name'] = $name; - - return $this; - } - - /** - * Get the cookie value - * - * @return string - */ - public function getValue() - { - return $this->data['Value']; - } - - /** - * Set the cookie value - * - * @param string $value Cookie value - * - * @return self - */ - public function setValue($value) - { - $this->data['Value'] = $value; - - return $this; - } - - /** - * Get the domain - * - * @return string|null - */ - public function getDomain() - { - return $this->data['Domain']; - } - - /** - * Set the domain of the cookie - * - * @param string $domain - * - * @return self - */ - public function setDomain($domain) - { - $this->data['Domain'] = $domain; - - return $this; - } - - /** - * Get the path - * - * @return string - */ - public function getPath() - { - return $this->data['Path']; - } - - /** - * Set the path of the cookie - * - * @param string $path Path of the cookie - * - * @return self - */ - public function setPath($path) - { - $this->data['Path'] = $path; - - return $this; - } - - /** - * Maximum lifetime of the cookie in seconds - * - * @return int|null - */ - public function getMaxAge() - { - return $this->data['Max-Age']; - } - - /** - * Set the max-age of the cookie - * - * @param int $maxAge Max age of the cookie in seconds - * - * @return self - */ - public function setMaxAge($maxAge) - { - $this->data['Max-Age'] = $maxAge; - - return $this; - } - - /** - * The UNIX timestamp when the cookie Expires - * - * @return mixed - */ - public function getExpires() - { - return $this->data['Expires']; - } - - /** - * Set the unix timestamp for which the cookie will expire - * - * @param int $timestamp Unix timestamp - * - * @return self - */ - public function setExpires($timestamp) - { - $this->data['Expires'] = is_numeric($timestamp) - ? (int) $timestamp - : strtotime($timestamp); - - return $this; - } - - /** - * Get whether or not this is a secure cookie - * - * @return null|bool - */ - public function getSecure() - { - return $this->data['Secure']; - } - - /** - * Set whether or not the cookie is secure - * - * @param bool $secure Set to true or false if secure - * - * @return self - */ - public function setSecure($secure) - { - $this->data['Secure'] = $secure; - - return $this; - } - - /** - * Get whether or not this is a session cookie - * - * @return null|bool - */ - public function getDiscard() - { - return $this->data['Discard']; - } - - /** - * Set whether or not this is a session cookie - * - * @param bool $discard Set to true or false if this is a session cookie - * - * @return self - */ - public function setDiscard($discard) - { - $this->data['Discard'] = $discard; - - return $this; - } - - /** - * Get whether or not this is an HTTP only cookie - * - * @return bool - */ - public function getHttpOnly() - { - return $this->data['HttpOnly']; - } - - /** - * Set whether or not this is an HTTP only cookie - * - * @param bool $httpOnly Set to true or false if this is HTTP only - * - * @return self - */ - public function setHttpOnly($httpOnly) - { - $this->data['HttpOnly'] = $httpOnly; - - return $this; - } - - /** - * Check if the cookie matches a path value - * - * @param string $path Path to check against - * - * @return bool - */ - public function matchesPath($path) - { - return !$this->getPath() || 0 === stripos($path, $this->getPath()); - } - - /** - * Check if the cookie matches a domain value - * - * @param string $domain Domain to check against - * - * @return bool - */ - public function matchesDomain($domain) - { - // Remove the leading '.' as per spec in RFC 6265. - // http://tools.ietf.org/html/rfc6265#section-5.2.3 - $cookieDomain = ltrim($this->getDomain(), '.'); - - // Domain not set or exact match. - if (!$cookieDomain || !strcasecmp($domain, $cookieDomain)) { - return true; - } - - // Matching the subdomain according to RFC 6265. - // http://tools.ietf.org/html/rfc6265#section-5.1.3 - if (filter_var($domain, FILTER_VALIDATE_IP)) { - return false; - } - - return (bool) preg_match('/\.' . preg_quote($cookieDomain) . '$/i', $domain); - } - - /** - * Check if the cookie is expired - * - * @return bool - */ - public function isExpired() - { - return $this->getExpires() && time() > $this->getExpires(); - } - - /** - * Check if the cookie is valid according to RFC 6265 - * - * @return bool|string Returns true if valid or an error message if invalid - */ - public function validate() - { - // Names must not be empty, but can be 0 - $name = $this->getName(); - if (empty($name) && !is_numeric($name)) { - return 'The cookie name must not be empty'; - } - - // Check if any of the invalid characters are present in the cookie name - if (preg_match("/[=,; \t\r\n\013\014]/", $name)) { - return "Cookie name must not cannot invalid characters: =,; \\t\\r\\n\\013\\014"; - } - - // Value must not be empty, but can be 0 - $value = $this->getValue(); - if (empty($value) && !is_numeric($value)) { - return 'The cookie value must not be empty'; - } - - // Domains must not be empty, but can be 0 - // A "0" is not a valid internet domain, but may be used as server name - // in a private network. - $domain = $this->getDomain(); - if (empty($domain) && !is_numeric($domain)) { - return 'The cookie domain must not be empty'; - } - - return true; - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Event/AbstractEvent.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Event/AbstractEvent.php deleted file mode 100644 index fa1453c84206fc035c9ce2324ec68fa59e686f33..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Event/AbstractEvent.php +++ /dev/null @@ -1,21 +0,0 @@ -propagationStopped; - } - - public function stopPropagation() - { - $this->propagationStopped = true; - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Event/AbstractRequestEvent.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Event/AbstractRequestEvent.php deleted file mode 100644 index d188248ac6f495779cafe37bea3b18a086eb2e57..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Event/AbstractRequestEvent.php +++ /dev/null @@ -1,49 +0,0 @@ -transaction = $transaction; - } - - /** - * Get the client associated with the event - * - * @return ClientInterface - */ - public function getClient() - { - return $this->transaction->getClient(); - } - - /** - * Get the request object - * - * @return RequestInterface - */ - public function getRequest() - { - return $this->transaction->getRequest(); - } - - /** - * @return TransactionInterface - */ - protected function getTransaction() - { - return $this->transaction; - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Event/AbstractTransferEvent.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Event/AbstractTransferEvent.php deleted file mode 100644 index dba1f98eb70c137cf2d27625a38db28003e18d58..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Event/AbstractTransferEvent.php +++ /dev/null @@ -1,83 +0,0 @@ -transferInfo = $transferInfo; - } - - /** - * Get all transfer information as an associative array if no $name - * argument is supplied, or gets a specific transfer statistic if - * a $name attribute is supplied (e.g., 'total_time'). - * - * @param string $name Name of the transfer stat to retrieve - * - * @return mixed|null|array - */ - public function getTransferInfo($name = null) - { - if (!$name) { - return $this->transferInfo; - } - - return isset($this->transferInfo[$name]) - ? $this->transferInfo[$name] - : null; - } - - /** - * Get the response - * - * @return ResponseInterface|null - */ - abstract public function getResponse(); - - /** - * Intercept the request and associate a response - * - * @param ResponseInterface $response Response to set - */ - abstract public function intercept(ResponseInterface $response); -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Event/BeforeEvent.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Event/BeforeEvent.php deleted file mode 100644 index 34a7811d6dce263594215f2e8213b91b285bdb4e..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Event/BeforeEvent.php +++ /dev/null @@ -1,26 +0,0 @@ -getTransaction()->setResponse($response); - $this->stopPropagation(); - RequestEvents::emitComplete($this->getTransaction()); - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Event/CompleteEvent.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Event/CompleteEvent.php deleted file mode 100644 index 344576001ae151b398c682c90804021970e4c156..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Event/CompleteEvent.php +++ /dev/null @@ -1,35 +0,0 @@ -stopPropagation(); - $this->getTransaction()->setResponse($response); - } - - /** - * Get the response of the request - * - * @return ResponseInterface - */ - public function getResponse() - { - return $this->getTransaction()->getResponse(); - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Event/Emitter.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Event/Emitter.php deleted file mode 100644 index 49172bcb50bad513c51efe10f57dc70f589c45b3..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Event/Emitter.php +++ /dev/null @@ -1,147 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - * - * @link https://github.com/symfony/symfony/tree/master/src/Symfony/Component/EventDispatcher - */ -class Emitter implements EmitterInterface -{ - /** @var array */ - private $listeners = []; - - /** @var array */ - private $sorted = []; - - public function on($eventName, callable $listener, $priority = 0) - { - if ($priority === 'first') { - $priority = isset($this->listeners[$eventName]) - ? max(array_keys($this->listeners[$eventName])) + 1 - : 1; - } elseif ($priority === 'last') { - $priority = isset($this->listeners[$eventName]) - ? min(array_keys($this->listeners[$eventName])) - 1 - : -1; - } - - $this->listeners[$eventName][$priority][] = $listener; - unset($this->sorted[$eventName]); - } - - public function once($eventName, callable $listener, $priority = 0) - { - $onceListener = function ( - EventInterface $event, - $eventName - ) use (&$onceListener, $eventName, $listener, $priority) { - $this->removeListener($eventName, $onceListener); - $listener($event, $eventName, $this); - }; - - $this->on($eventName, $onceListener, $priority); - } - - public function removeListener($eventName, callable $listener) - { - if (!isset($this->listeners[$eventName])) { - return; - } - - foreach ($this->listeners[$eventName] as $priority => $listeners) { - if (false !== ($key = array_search($listener, $listeners, true))) { - unset( - $this->listeners[$eventName][$priority][$key], - $this->sorted[$eventName] - ); - } - } - } - - public function listeners($eventName = null) - { - // Return all events in a sorted priority order - if ($eventName === null) { - foreach (array_keys($this->listeners) as $eventName) { - if (!isset($this->sorted[$eventName])) { - $this->listeners($eventName); - } - } - return $this->sorted; - } - - // Return the listeners for a specific event, sorted in priority order - if (!isset($this->sorted[$eventName])) { - if (!isset($this->listeners[$eventName])) { - return []; - } else { - krsort($this->listeners[$eventName]); - $this->sorted[$eventName] = call_user_func_array( - 'array_merge', - $this->listeners[$eventName] - ); - } - } - - return $this->sorted[$eventName]; - } - - public function emit($eventName, EventInterface $event) - { - if (isset($this->listeners[$eventName])) { - foreach ($this->listeners($eventName) as $listener) { - $listener($event, $eventName); - if ($event->isPropagationStopped()) { - break; - } - } - } - - return $event; - } - - public function attach(SubscriberInterface $subscriber) - { - foreach ($subscriber->getEvents() as $eventName => $listener) { - $this->on( - $eventName, - array($subscriber, $listener[0]), - isset($listener[1]) ? $listener[1] : 0 - ); - } - } - - public function detach(SubscriberInterface $subscriber) - { - foreach ($subscriber->getEvents() as $eventName => $listener) { - $this->removeListener($eventName, array($subscriber, $listener[0])); - } - } - - public function __call($name, $arguments) - { - return \GuzzleHttp\deprecation_proxy( - $this, - $name, - $arguments, - [ - 'addSubscriber' => 'attach', - 'removeSubscriber' => 'detach', - 'addListener' => 'on', - 'dispatch' => 'emit' - ] - ); - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Event/EmitterInterface.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Event/EmitterInterface.php deleted file mode 100644 index 0181e7fe713aaa2cff9d40a5f0cb8ce7c2fd1083..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Event/EmitterInterface.php +++ /dev/null @@ -1,88 +0,0 @@ -exception = $e; - } - - /** - * Intercept the exception and inject a response - * - * @param ResponseInterface $response Response to set - */ - public function intercept(ResponseInterface $response) - { - $this->stopPropagation(); - $this->getTransaction()->setResponse($response); - RequestEvents::emitComplete($this->getTransaction()); - } - - /** - * Get the exception that was encountered - * - * @return RequestException - */ - public function getException() - { - return $this->exception; - } - - /** - * Get the response the was received (if any) - * - * @return ResponseInterface|null - */ - public function getResponse() - { - return $this->getException()->getResponse(); - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Event/EventInterface.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Event/EventInterface.php deleted file mode 100644 index bf58f8b5146b93894fe687311ded6b012651b80d..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Event/EventInterface.php +++ /dev/null @@ -1,24 +0,0 @@ -emitter) { - $this->emitter = new Emitter(); - } - - return $this->emitter; - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Event/HeadersEvent.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Event/HeadersEvent.php deleted file mode 100644 index 81274ff84a670d48f65a8e51cd2b3793cd1844cf..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Event/HeadersEvent.php +++ /dev/null @@ -1,39 +0,0 @@ -getResponse()) { - throw new \RuntimeException('A response must be present'); - } - } - - /** - * Get the response the was received - * - * @return ResponseInterface - */ - public function getResponse() - { - return $this->getTransaction()->getResponse(); - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Event/ListenerAttacherTrait.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Event/ListenerAttacherTrait.php deleted file mode 100644 index 637cdaea6ab9af312f9adc97e3900117037fde18..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Event/ListenerAttacherTrait.php +++ /dev/null @@ -1,89 +0,0 @@ -getEmitter(); - foreach ($listeners as $el) { - if ($el['once']) { - $emitter->once($el['name'], $el['fn'], $el['priority']); - } else { - $emitter->on($el['name'], $el['fn'], $el['priority']); - } - } - } - - /** - * Extracts the allowed events from the provided array, and ignores anything - * else in the array. The event listener must be specified as a callable or - * as an array of event listener data ("name", "fn", "priority", "once"). - * - * @param array $source Array containing callables or hashes of data to be - * prepared as event listeners. - * @param array $events Names of events to look for in the provided $source - * array. Other keys are ignored. - * @return array - */ - private function prepareListeners(array $source, array $events) - { - $listeners = []; - foreach ($events as $name) { - if (isset($source[$name])) { - $this->buildListener($name, $source[$name], $listeners); - } - } - - return $listeners; - } - - /** - * Creates a complete event listener definition from the provided array of - * listener data. Also works recursively if more than one listeners are - * contained in the provided array. - * - * @param string $name Name of the event the listener is for. - * @param array|callable $data Event listener data to prepare. - * @param array $listeners Array of listeners, passed by reference. - * - * @throws \InvalidArgumentException if the event data is malformed. - */ - private function buildListener($name, $data, &$listeners) - { - static $defaults = ['priority' => 0, 'once' => false]; - - // If a callable is provided, normalize it to the array format. - if (is_callable($data)) { - $data = ['fn' => $data]; - } - - // Prepare the listener and add it to the array, recursively. - if (isset($data['fn'])) { - $data['name'] = $name; - $listeners[] = $data + $defaults; - } elseif (is_array($data)) { - foreach ($data as $listenerData) { - $this->buildListener($name, $listenerData, $listeners); - } - } else { - throw new \InvalidArgumentException('Each event listener must be a ' - . 'callable or an associative array containing a "fn" key.'); - } - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Event/RequestEvents.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Event/RequestEvents.php deleted file mode 100644 index 654e8ad0219042490b1284d5d3da81323364029f..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Event/RequestEvents.php +++ /dev/null @@ -1,162 +0,0 @@ -getRequest(); - try { - $request->getEmitter()->emit( - 'before', - new BeforeEvent($transaction) - ); - } catch (RequestException $e) { - // When a RequestException has been emitted through emitError, the - // exception is marked as "emitted". This means that the exception - // had a chance to be rescued but was not. In this case, this method - // must not emit the error again, but rather throw the exception. - // This prevents RequestExceptions encountered during the before - // event from being emitted to listeners twice. - if ($e->emittedError()) { - throw $e; - } - self::emitError($transaction, $e); - } catch (\Exception $e) { - self::emitError($transaction, $e); - } - } - - /** - * Emits the complete event for a request and emits an error - * event if an error is encountered during the after send. - * - * @param TransactionInterface $transaction Transaction to emit for - * @param array $stats Transfer stats - * - * @throws RequestException - */ - public static function emitComplete( - TransactionInterface $transaction, - array $stats = [] - ) { - $request = $transaction->getRequest(); - $transaction->getResponse()->setEffectiveUrl($request->getUrl()); - try { - $request->getEmitter()->emit( - 'complete', - new CompleteEvent($transaction, $stats) - ); - } catch (RequestException $e) { - self::emitError($transaction, $e, $stats); - } - } - - /** - * Emits the headers event for a request. - * - * @param TransactionInterface $transaction Transaction to emit for - */ - public static function emitHeaders(TransactionInterface $transaction) - { - $transaction->getRequest()->getEmitter()->emit( - 'headers', - new HeadersEvent($transaction) - ); - } - - /** - * Emits an error event for a request and accounts for the propagation - * of an error event being stopped to prevent the exception from being - * thrown. - * - * @param TransactionInterface $transaction - * @param \Exception $e - * @param array $stats - * - * @throws \GuzzleHttp\Exception\RequestException - */ - public static function emitError( - TransactionInterface $transaction, - \Exception $e, - array $stats = [] - ) { - $request = $transaction->getRequest(); - - // Convert non-request exception to a wrapped exception - if (!($e instanceof RequestException)) { - $e = new RequestException($e->getMessage(), $request, null, $e); - } - - // Mark the exception as having been emitted for an error event. This - // works in tandem with the emitBefore method to prevent the error - // event from being triggered twice for the same exception. - $e->emittedError(true); - - // Dispatch an event and allow interception - if (!$request->getEmitter()->emit( - 'error', - new ErrorEvent($transaction, $e, $stats) - )->isPropagationStopped()) { - throw $e; - } - } - - /** - * Converts an array of event options into a formatted array of valid event - * configuration. - * - * @param array $options Event array to convert - * @param array $events Event names to convert in the options array. - * @param mixed $handler Event handler to utilize - * - * @return array - * @throws \InvalidArgumentException if the event config is invalid - * @internal - */ - public static function convertEventArray( - array $options, - array $events, - $handler - ) { - foreach ($events as $name) { - if (!isset($options[$name])) { - $options[$name] = $handler; - } elseif (is_callable($options[$name])) { - $options[$name] = [['fn' => $options[$name]], $handler]; - } elseif (is_array($options[$name])) { - $options[$name][] = $handler; - } else { - throw new \InvalidArgumentException('Invalid event format'); - } - } - - return $options; - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Event/SubscriberInterface.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Event/SubscriberInterface.php deleted file mode 100644 index 22c7311900f8786c67b0efdea25072053f5546cd..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Event/SubscriberInterface.php +++ /dev/null @@ -1,31 +0,0 @@ - ['methodName']] - * - ['eventName' => ['methodName', $priority]] - * - * @return array - */ - public function getEvents(); -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Exception/AdapterException.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Exception/AdapterException.php deleted file mode 100644 index 55334c464c2132daaba5a7d6c463f6675d6c14e5..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Exception/AdapterException.php +++ /dev/null @@ -1,5 +0,0 @@ -response = $response; - } - /** - * Get the associated response - * - * @return ResponseInterface|null - */ - public function getResponse() - { - return $this->response; - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Exception/RequestException.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Exception/RequestException.php deleted file mode 100644 index ee953a9c742d580453d73e9178aa3965aa1ffcb2..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Exception/RequestException.php +++ /dev/null @@ -1,124 +0,0 @@ -getStatusCode() : 0; - parent::__construct($message, $code, $previous); - $this->request = $request; - $this->response = $response; - } - - /** - * Factory method to create a new exception with a normalized error message - * - * @param RequestInterface $request Request - * @param ResponseInterface $response Response received - * @param \Exception $previous Previous exception - * - * @return self - */ - public static function create( - RequestInterface $request, - ResponseInterface $response = null, - \Exception $previous = null - ) { - if (!$response) { - return new self('Error completing request', $request, null, $previous); - } - - $level = $response->getStatusCode()[0]; - if ($level == '4') { - $label = 'Client error response'; - $className = __NAMESPACE__ . '\\ClientException'; - } elseif ($level == '5') { - $label = 'Server error response'; - $className = __NAMESPACE__ . '\\ServerException'; - } else { - $label = 'Unsuccessful response'; - $className = __CLASS__; - } - - $message = $label . ' [url] ' . $request->getUrl() - . ' [status code] ' . $response->getStatusCode() - . ' [reason phrase] ' . $response->getReasonPhrase(); - - return new $className($message, $request, $response, $previous); - } - - /** - * Get the request that caused the exception - * - * @return RequestInterface - */ - public function getRequest() - { - return $this->request; - } - - /** - * Get the associated response - * - * @return ResponseInterface|null - */ - public function getResponse() - { - return $this->response; - } - - /** - * Check if a response was received - * - * @return bool - */ - public function hasResponse() - { - return $this->response !== null; - } - - /** - * Check or set if the exception was emitted in an error event. - * - * This value is used in the RequestEvents::emitBefore() method to check - * to see if an exception has already been emitted in an error event. - * - * @param bool|null Set to true to set the exception as having emitted an - * error. Leave null to retrieve the current setting. - * - * @return null|bool - * @throws \InvalidArgumentException if you attempt to set the value to false - */ - public function emittedError($value = null) - { - if ($value === null) { - return $this->emittedErrorEvent; - } elseif ($value === true) { - return $this->emittedErrorEvent = true; - } else { - throw new \InvalidArgumentException('You cannot set the emitted ' - . 'error value to false.'); - } - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Exception/ServerException.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Exception/ServerException.php deleted file mode 100644 index d67ed27e3429d7e75f5290abdc1baa0087ac3943..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Exception/ServerException.php +++ /dev/null @@ -1,8 +0,0 @@ -data); - } - - public function offsetGet($offset) - { - return isset($this->data[$offset]) ? $this->data[$offset] : null; - } - - public function offsetSet($offset, $value) - { - $this->data[$offset] = $value; - } - - public function offsetExists($offset) - { - return isset($this->data[$offset]); - } - - public function offsetUnset($offset) - { - unset($this->data[$offset]); - } - - public function toArray() - { - return $this->data; - } - - public function count() - { - return count($this->data); - } - - /** - * Get a value from the collection using a path syntax to retrieve nested - * data. - * - * @param string $path Path to traverse and retrieve a value from - * - * @return mixed|null - */ - public function getPath($path) - { - return \GuzzleHttp\get_path($this->data, $path); - } - - /** - * Set a value into a nested array key. Keys will be created as needed to - * set the value. - * - * @param string $path Path to set - * @param mixed $value Value to set at the key - * - * @throws \RuntimeException when trying to setPath using a nested path - * that travels through a scalar value - */ - public function setPath($path, $value) - { - \GuzzleHttp\set_path($this->data, $path, $value); - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Message/AbstractMessage.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Message/AbstractMessage.php deleted file mode 100644 index 6037a70e6a2801c3a3b3d88cb3bb59531a47055c..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Message/AbstractMessage.php +++ /dev/null @@ -1,237 +0,0 @@ -getStartLine(); - foreach ($this->getHeaders() as $name => $values) { - $result .= "\r\n{$name}: " . implode(', ', $values); - } - - return $result . "\r\n\r\n" . $this->body; - } - - public function getProtocolVersion() - { - return $this->protocolVersion; - } - - public function getBody() - { - return $this->body; - } - - public function setBody(StreamInterface $body = null) - { - if ($body === null) { - // Setting a null body will remove the body of the request - $this->removeHeader('Content-Length') - ->removeHeader('Transfer-Encoding'); - } - - $this->body = $body; - - return $this; - } - - public function addHeader($header, $value) - { - static $valid = ['string' => true, 'integer' => true, - 'double' => true, 'array' => true]; - - $type = gettype($value); - if (!isset($valid[$type])) { - throw new \InvalidArgumentException('Invalid header value'); - } - - if ($type == 'array') { - $current = array_merge($this->getHeader($header, true), $value); - } else { - $current = $this->getHeader($header, true); - $current[] = $value; - } - - return $this->setHeader($header, $current); - } - - public function addHeaders(array $headers) - { - foreach ($headers as $name => $header) { - $this->addHeader($name, $header); - } - } - - public function getHeader($header, $asArray = false) - { - $name = strtolower($header); - - if (!isset($this->headers[$name])) { - return $asArray ? [] : ''; - } - - return $asArray - ? $this->headers[$name] - : implode(', ', $this->headers[$name]); - } - - public function getHeaders() - { - $headers = []; - foreach ($this->headers as $name => $values) { - $headers[$this->headerNames[$name]] = $values; - } - - return $headers; - } - - public function setHeader($header, $value) - { - $header = trim($header); - $name = strtolower($header); - $this->headerNames[$name] = $header; - - switch (gettype($value)) { - case 'string': - $this->headers[$name] = [trim($value)]; - break; - case 'integer': - case 'double': - $this->headers[$name] = [(string) $value]; - break; - case 'array': - foreach ($value as &$v) { - $v = trim($v); - } - $this->headers[$name] = $value; - break; - default: - throw new \InvalidArgumentException('Invalid header value ' - . 'provided: ' . var_export($value, true)); - } - - return $this; - } - - public function setHeaders(array $headers) - { - $this->headers = $this->headerNames = []; - foreach ($headers as $key => $value) { - $this->setHeader($key, $value); - } - - return $this; - } - - public function hasHeader($header) - { - return isset($this->headers[strtolower($header)]); - } - - public function removeHeader($header) - { - $name = strtolower($header); - unset($this->headers[$name], $this->headerNames[$name]); - - return $this; - } - - /** - * Parse an array of header values containing ";" separated data into an - * array of associative arrays representing the header key value pair - * data of the header. When a parameter does not contain a value, but just - * contains a key, this function will inject a key with a '' string value. - * - * @param MessageInterface $message That contains the header - * @param string $header Header to retrieve from the message - * - * @return array Returns the parsed header values. - */ - public static function parseHeader(MessageInterface $message, $header) - { - static $trimmed = "\"' \n\t\r"; - $params = $matches = []; - - foreach (self::normalizeHeader($message, $header) as $val) { - $part = []; - foreach (preg_split('/;(?=([^"]*"[^"]*")*[^"]*$)/', $val) as $kvp) { - if (preg_match_all('/<[^>]+>|[^=]+/', $kvp, $matches)) { - $m = $matches[0]; - if (isset($m[1])) { - $part[trim($m[0], $trimmed)] = trim($m[1], $trimmed); - } else { - $part[] = trim($m[0], $trimmed); - } - } - } - if ($part) { - $params[] = $part; - } - } - - return $params; - } - - /** - * Converts an array of header values that may contain comma separated - * headers into an array of headers with no comma separated values. - * - * @param MessageInterface $message That contains the header - * @param string $header Header to retrieve from the message - * - * @return array Returns the normalized header field values. - */ - public static function normalizeHeader(MessageInterface $message, $header) - { - $h = $message->getHeader($header, true); - for ($i = 0, $total = count($h); $i < $total; $i++) { - if (strpos($h[$i], ',') === false) { - continue; - } - foreach (preg_split('/,(?=([^"]*"[^"]*")*[^"]*$)/', $h[$i]) as $v) { - $h[] = trim($v); - } - unset($h[$i]); - } - - return $h; - } - - /** - * Returns the start line of a message. - * - * @return string - */ - abstract protected function getStartLine(); - - /** - * Accepts and modifies the options provided to the message in the - * constructor. - * - * Can be overridden in subclasses as necessary. - * - * @param array $options Options array passed by reference. - */ - protected function handleOptions(array &$options) - { - if (isset($options['protocol_version'])) { - $this->protocolVersion = $options['protocol_version']; - } - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Message/MessageFactory.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Message/MessageFactory.php deleted file mode 100644 index da67c385767dc50f9a37625ac1b95bc7ac8f9671..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Message/MessageFactory.php +++ /dev/null @@ -1,345 +0,0 @@ -errorPlugin = new HttpError(); - $this->redirectPlugin = new Redirect(); - } - - public function createResponse( - $statusCode, - array $headers = [], - $body = null, - array $options = [] - ) { - if (null !== $body) { - $body = Stream\create($body); - } - - return new Response($statusCode, $headers, $body, $options); - } - - public function createRequest($method, $url, array $options = []) - { - // Handle the request protocol version option that needs to be - // specified in the request constructor. - if (isset($options['version'])) { - $options['config']['protocol_version'] = $options['version']; - unset($options['version']); - } - - $request = new Request($method, $url, [], null, - isset($options['config']) ? $options['config'] : []); - - unset($options['config']); - - // Use a POST body by default - if ($method == 'POST' && - !isset($options['body']) && - !isset($options['json']) - ) { - $options['body'] = []; - } - - if ($options) { - $this->applyOptions($request, $options); - } - - return $request; - } - - /** - * Create a request or response object from an HTTP message string - * - * @param string $message Message to parse - * - * @return RequestInterface|ResponseInterface - * @throws \InvalidArgumentException if unable to parse a message - */ - public function fromMessage($message) - { - static $parser; - if (!$parser) { - $parser = new MessageParser(); - } - - // Parse a response - if (strtoupper(substr($message, 0, 4)) == 'HTTP') { - $data = $parser->parseResponse($message); - return $this->createResponse( - $data['code'], - $data['headers'], - $data['body'] === '' ? null : $data['body'], - $data - ); - } - - // Parse a request - if (!($data = ($parser->parseRequest($message)))) { - throw new \InvalidArgumentException('Unable to parse request'); - } - - return $this->createRequest( - $data['method'], - Url::buildUrl($data['request_url']), - [ - 'headers' => $data['headers'], - 'body' => $data['body'] === '' ? null : $data['body'], - 'config' => [ - 'protocol_version' => $data['protocol_version'] - ] - ] - ); - } - - /** - * Apply POST fields and files to a request to attempt to give an accurate - * representation. - * - * @param RequestInterface $request Request to update - * @param array $body Body to apply - */ - protected function addPostData(RequestInterface $request, array $body) - { - static $fields = ['string' => true, 'array' => true, 'NULL' => true, - 'boolean' => true, 'double' => true, 'integer' => true]; - - $post = new PostBody(); - foreach ($body as $key => $value) { - if (isset($fields[gettype($value)])) { - $post->setField($key, $value); - } elseif ($value instanceof PostFileInterface) { - $post->addFile($value); - } else { - $post->addFile(new PostFile($key, $value)); - } - } - - $request->setBody($post); - $post->applyRequestHeaders($request); - } - - protected function applyOptions( - RequestInterface $request, - array $options = [] - ) { - // Values specified in the config map are passed to request options - static $configMap = ['connect_timeout' => 1, 'timeout' => 1, - 'verify' => 1, 'ssl_key' => 1, 'cert' => 1, 'proxy' => 1, - 'debug' => 1, 'save_to' => 1, 'stream' => 1, 'expect' => 1]; - - // Take the class of the instance, not the parent - $selfClass = get_class($this); - - // Check if we already took it's class methods and had them saved - if (!isset(self::$classMethods[$selfClass])) { - self::$classMethods[$selfClass] = array_flip(get_class_methods($this)); - } - - // Take class methods of this particular instance - $methods = self::$classMethods[$selfClass]; - - // Iterate over each key value pair and attempt to apply a config using - // double dispatch. - $config = $request->getConfig(); - foreach ($options as $key => $value) { - $method = "add_{$key}"; - if (isset($methods[$method])) { - $this->{$method}($request, $value); - } elseif (isset($configMap[$key])) { - $config[$key] = $value; - } else { - throw new \InvalidArgumentException("No method is configured " - . "to handle the {$key} config key"); - } - } - } - - private function add_body(RequestInterface $request, $value) - { - if ($value !== null) { - if (is_array($value)) { - $this->addPostData($request, $value); - } else { - $request->setBody(Stream\create($value)); - } - } - } - - private function add_allow_redirects(RequestInterface $request, $value) - { - static $defaultRedirect = [ - 'max' => 5, - 'strict' => false, - 'referer' => false - ]; - - if ($value === false) { - return; - } - - if ($value === true) { - $value = $defaultRedirect; - } elseif (!isset($value['max'])) { - throw new \InvalidArgumentException('allow_redirects must be ' - . 'true, false, or an array that contains the \'max\' key'); - } else { - // Merge the default settings with the provided settings - $value += $defaultRedirect; - } - - $request->getConfig()['redirect'] = $value; - $request->getEmitter()->attach($this->redirectPlugin); - } - - private function add_exceptions(RequestInterface $request, $value) - { - if ($value === true) { - $request->getEmitter()->attach($this->errorPlugin); - } - } - - private function add_auth(RequestInterface $request, $value) - { - if (!$value) { - return; - } elseif (is_array($value)) { - $authType = isset($value[2]) ? strtolower($value[2]) : 'basic'; - } else { - $authType = strtolower($value); - } - - $request->getConfig()->set('auth', $value); - - if ($authType == 'basic') { - $request->setHeader( - 'Authorization', - 'Basic ' . base64_encode("$value[0]:$value[1]") - ); - } elseif ($authType == 'digest') { - // Currently only implemented by the cURL adapter. - // @todo: Need an event listener solution that does not rely on cURL - $config = $request->getConfig(); - $config->setPath('curl/' . CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); - $config->setPath('curl/' . CURLOPT_USERPWD, "$value[0]:$value[1]"); - } - } - - private function add_query(RequestInterface $request, $value) - { - if ($value instanceof Query) { - $original = $request->getQuery(); - // Do not overwrite existing query string variables by overwriting - // the object with the query string data passed in the URL - $request->setQuery($value->overwriteWith($original->toArray())); - } elseif (is_array($value)) { - // Do not overwrite existing query string variables - $query = $request->getQuery(); - foreach ($value as $k => $v) { - if (!isset($query[$k])) { - $query[$k] = $v; - } - } - } else { - throw new \InvalidArgumentException('query value must be an array ' - . 'or Query object'); - } - } - - private function add_headers(RequestInterface $request, $value) - { - if (!is_array($value)) { - throw new \InvalidArgumentException('header value must be an array'); - } - - // Do not overwrite existing headers - foreach ($value as $k => $v) { - if (!$request->hasHeader($k)) { - $request->setHeader($k, $v); - } - } - } - - private function add_cookies(RequestInterface $request, $value) - { - if ($value === true) { - static $cookie = null; - if (!$cookie) { - $cookie = new Cookie(); - } - $request->getEmitter()->attach($cookie); - } elseif (is_array($value)) { - $request->getEmitter()->attach( - new Cookie(CookieJar::fromArray($value, $request->getHost())) - ); - } elseif ($value instanceof CookieJarInterface) { - $request->getEmitter()->attach(new Cookie($value)); - } elseif ($value !== false) { - throw new \InvalidArgumentException('cookies must be an array, ' - . 'true, or a CookieJarInterface object'); - } - } - - private function add_events(RequestInterface $request, $value) - { - if (!is_array($value)) { - throw new \InvalidArgumentException('events value must be an array'); - } - - $this->attachListeners($request, $this->prepareListeners($value, - ['before', 'complete', 'error', 'headers'] - )); - } - - private function add_subscribers(RequestInterface $request, $value) - { - if (!is_array($value)) { - throw new \InvalidArgumentException('subscribers must be an array'); - } - - $emitter = $request->getEmitter(); - foreach ($value as $subscribers) { - $emitter->attach($subscribers); - } - } - - private function add_json(RequestInterface $request, $value) - { - if (!$request->hasHeader('Content-Type')) { - $request->setHeader('Content-Type', 'application/json'); - } - - $request->setBody(Stream\create(json_encode($value))); - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Message/MessageFactoryInterface.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Message/MessageFactoryInterface.php deleted file mode 100644 index daab04273a2f84ae03f76879fd679e0b6bfd605b..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Message/MessageFactoryInterface.php +++ /dev/null @@ -1,71 +0,0 @@ -getHeaders() as $name => $values) { - * echo $name . ": " . implode(", ", $values); - * } - * - * @return array Returns an associative array of the message's headers. - */ - public function getHeaders(); - - /** - * Retrieve a header by the given case-insensitive name. - * - * By default, this method returns all of the header values of the given - * case-insensitive header name as a string concatenated together using - * a comma. Because some header should not be concatenated together using a - * comma, this method provides a Boolean argument that can be used to - * retrieve the associated header values as an array of strings. - * - * @param string $header Case-insensitive header name. - * @param bool $asArray Set to true to retrieve the header value as an - * array of strings. - * - * @return array|string - */ - public function getHeader($header, $asArray = false); - - /** - * Checks if a header exists by the given case-insensitive name. - * - * @param string $header Case-insensitive header name. - * - * @return bool Returns true if any header names match the given header - * name using a case-insensitive string comparison. Returns false if - * no matching header name is found in the message. - */ - public function hasHeader($header); - - /** - * Remove a specific header by case-insensitive name. - * - * @param string $header Case-insensitive header name. - * - * @return self - */ - public function removeHeader($header); - - /** - * Appends a header value to any existing values associated with the - * given header name. - * - * @param string $header Header name to add - * @param string $value Value of the header - * - * @return self - */ - public function addHeader($header, $value); - - /** - * Merges in an associative array of headers. - * - * Each array key MUST be a string representing the case-insensitive name - * of a header. Each value MUST be either a string or an array of strings. - * For each value, the value is appended to any existing header of the same - * name, or, if a header does not already exist by the given name, then the - * header is added. - * - * @param array $headers Associative array of headers to add to the message - * - * @return self - */ - public function addHeaders(array $headers); - - /** - * Sets a header, replacing any existing values of any headers with the - * same case-insensitive name. - * - * The header values MUST be a string or an array of strings. - * - * @param string $header Header name - * @param string|array $value Header value(s) - * - * @return self Returns the message. - */ - public function setHeader($header, $value); - - /** - * Sets headers, replacing any headers that have already been set on the - * message. - * - * The array keys MUST be a string. The array values must be either a - * string or an array of strings. - * - * @param array $headers Headers to set. - * - * @return self Returns the message. - */ - public function setHeaders(array $headers); -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Message/MessageParser.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Message/MessageParser.php deleted file mode 100644 index 777ce26e9d7c8c5bf2c6feb7a4ceb66f87eced7d..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Message/MessageParser.php +++ /dev/null @@ -1,172 +0,0 @@ -parseMessage($message))) { - return false; - } - - // Parse the protocol and protocol version - if (isset($parts['start_line'][2])) { - $startParts = explode('/', $parts['start_line'][2]); - $protocol = strtoupper($startParts[0]); - $version = isset($startParts[1]) ? $startParts[1] : '1.1'; - } else { - $protocol = 'HTTP'; - $version = '1.1'; - } - - $parsed = [ - 'method' => strtoupper($parts['start_line'][0]), - 'protocol' => $protocol, - 'protocol_version' => $version, - 'headers' => $parts['headers'], - 'body' => $parts['body'] - ]; - - $parsed['request_url'] = $this->getUrlPartsFromMessage( - (isset($parts['start_line'][1]) ? $parts['start_line'][1] : ''), $parsed); - - return $parsed; - } - - /** - * Parse an HTTP response message into an associative array of parts. - * - * @param string $message HTTP response to parse - * - * @return array|bool Returns false if the message is invalid - */ - public function parseResponse($message) - { - if (!($parts = $this->parseMessage($message))) { - return false; - } - - list($protocol, $version) = explode('/', trim($parts['start_line'][0])); - - return [ - 'protocol' => $protocol, - 'protocol_version' => $version, - 'code' => $parts['start_line'][1], - 'reason_phrase' => isset($parts['start_line'][2]) ? $parts['start_line'][2] : '', - 'headers' => $parts['headers'], - 'body' => $parts['body'] - ]; - } - - /** - * Parse a message into parts - * - * @param string $message Message to parse - * - * @return array|bool - */ - private function parseMessage($message) - { - if (!$message) { - return false; - } - - $startLine = null; - $headers = []; - $body = ''; - - // Iterate over each line in the message, accounting for line endings - $lines = preg_split('/(\\r?\\n)/', $message, -1, PREG_SPLIT_DELIM_CAPTURE); - for ($i = 0, $totalLines = count($lines); $i < $totalLines; $i += 2) { - - $line = $lines[$i]; - - // If two line breaks were encountered, then this is the end of body - if (empty($line)) { - if ($i < $totalLines - 1) { - $body = implode('', array_slice($lines, $i + 2)); - } - break; - } - - // Parse message headers - if (!$startLine) { - $startLine = explode(' ', $line, 3); - } elseif (strpos($line, ':')) { - $parts = explode(':', $line, 2); - $key = trim($parts[0]); - $value = isset($parts[1]) ? trim($parts[1]) : ''; - if (!isset($headers[$key])) { - $headers[$key] = $value; - } elseif (!is_array($headers[$key])) { - $headers[$key] = [$headers[$key], $value]; - } else { - $headers[$key][] = $value; - } - } - } - - return [ - 'start_line' => $startLine, - 'headers' => $headers, - 'body' => $body - ]; - } - - /** - * Create URL parts from HTTP message parts - * - * @param string $requestUrl Associated URL - * @param array $parts HTTP message parts - * - * @return array - */ - private function getUrlPartsFromMessage($requestUrl, array $parts) - { - // Parse the URL information from the message - $urlParts = ['path' => $requestUrl, 'scheme' => 'http']; - - // Check for the Host header - if (isset($parts['headers']['Host'])) { - $urlParts['host'] = $parts['headers']['Host']; - } elseif (isset($parts['headers']['host'])) { - $urlParts['host'] = $parts['headers']['host']; - } else { - $urlParts['host'] = null; - } - - if (false === strpos($urlParts['host'], ':')) { - $urlParts['port'] = ''; - } else { - $hostParts = explode(':', $urlParts['host']); - $urlParts['host'] = trim($hostParts[0]); - $urlParts['port'] = (int) trim($hostParts[1]); - if ($urlParts['port'] == 443) { - $urlParts['scheme'] = 'https'; - } - } - - // Check if a query is present - $path = $urlParts['path']; - $qpos = strpos($path, '?'); - if ($qpos) { - $urlParts['query'] = substr($path, $qpos + 1); - $urlParts['path'] = substr($path, 0, $qpos); - } else { - $urlParts['query'] = ''; - } - - return $urlParts; - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Message/Request.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Message/Request.php deleted file mode 100644 index 5c0e0aefbd5e615432496fdf47203a21d80cfd19..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Message/Request.php +++ /dev/null @@ -1,216 +0,0 @@ -setUrl($url); - $this->method = strtoupper($method); - $this->handleOptions($options); - $this->transferOptions = new Collection($options); - $this->addPrepareEvent(); - - if ($body !== null) { - $this->setBody($body); - } - - if ($headers) { - foreach ($headers as $key => $value) { - $this->setHeader($key, $value); - } - } - } - - public function __clone() - { - if ($this->emitter) { - $this->emitter = clone $this->emitter; - } - $this->transferOptions = clone $this->transferOptions; - $this->url = clone $this->url; - } - - public function setUrl($url) - { - $this->url = $url instanceof Url ? $url : Url::fromString($url); - $this->updateHostHeaderFromUrl(); - - return $this; - } - - public function getUrl() - { - return (string) $this->url; - } - - public function setQuery($query) - { - $this->url->setQuery($query); - - return $this; - } - - public function getQuery() - { - return $this->url->getQuery(); - } - - public function setMethod($method) - { - $this->method = strtoupper($method); - - return $this; - } - - public function getMethod() - { - return $this->method; - } - - public function getScheme() - { - return $this->url->getScheme(); - } - - public function setScheme($scheme) - { - $this->url->setScheme($scheme); - - return $this; - } - - public function getPort() - { - return $this->url->getPort(); - } - - public function setPort($port) - { - $this->url->setPort($port); - $this->updateHostHeaderFromUrl(); - - return $this; - } - - public function getHost() - { - return $this->url->getHost(); - } - - public function setHost($host) - { - $this->url->setHost($host); - $this->updateHostHeaderFromUrl(); - - return $this; - } - - public function getPath() - { - return '/' . ltrim($this->url->getPath(), '/'); - } - - public function setPath($path) - { - $this->url->setPath($path); - - return $this; - } - - public function getResource() - { - $resource = $this->getPath(); - if ($query = (string) $this->url->getQuery()) { - $resource .= '?' . $query; - } - - return $resource; - } - - public function getConfig() - { - return $this->transferOptions; - } - - protected function handleOptions(array &$options) - { - parent::handleOptions($options); - // Use a custom emitter if one is specified, and remove it from - // options that are exposed through getConfig() - if (isset($options['emitter'])) { - $this->emitter = $options['emitter']; - unset($options['emitter']); - } - } - - protected function getStartLine() - { - return trim($this->method . ' ' . $this->getResource()) - . ' HTTP/' . $this->getProtocolVersion(); - } - - /** - * Adds a subscriber that ensures a request's body is prepared before - * sending. - */ - private function addPrepareEvent() - { - static $subscriber; - if (!$subscriber) { - $subscriber = new Prepare(); - } - - $this->getEmitter()->attach($subscriber); - } - - private function updateHostHeaderFromUrl() - { - $port = $this->url->getPort(); - $scheme = $this->url->getScheme(); - if ($host = $this->url->getHost()) { - if (($port == 80 && $scheme == 'http') || - ($port == 443 && $scheme == 'https') - ) { - $this->setHeader('Host', $host); - } else { - $this->setHeader('Host', "{$host}:{$port}"); - } - } - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Message/RequestInterface.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Message/RequestInterface.php deleted file mode 100644 index 8cd5de7be8ff766661bf6d0b4df2cacb3b8fe2f0..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Message/RequestInterface.php +++ /dev/null @@ -1,150 +0,0 @@ - 'Continue', - 101 => 'Switching Protocols', - 102 => 'Processing', - 200 => 'OK', - 201 => 'Created', - 202 => 'Accepted', - 203 => 'Non-Authoritative Information', - 204 => 'No Content', - 205 => 'Reset Content', - 206 => 'Partial Content', - 207 => 'Multi-Status', - 208 => 'Already Reported', - 226 => 'IM Used', - 300 => 'Multiple Choices', - 301 => 'Moved Permanently', - 302 => 'Found', - 303 => 'See Other', - 304 => 'Not Modified', - 305 => 'Use Proxy', - 307 => 'Temporary Redirect', - 308 => 'Permanent Redirect', - 400 => 'Bad Request', - 401 => 'Unauthorized', - 402 => 'Payment Required', - 403 => 'Forbidden', - 404 => 'Not Found', - 405 => 'Method Not Allowed', - 406 => 'Not Acceptable', - 407 => 'Proxy Authentication Required', - 408 => 'Request Timeout', - 409 => 'Conflict', - 410 => 'Gone', - 411 => 'Length Required', - 412 => 'Precondition Failed', - 413 => 'Request Entity Too Large', - 414 => 'Request-URI Too Long', - 415 => 'Unsupported Media Type', - 416 => 'Requested Range Not Satisfiable', - 417 => 'Expectation Failed', - 422 => 'Unprocessable Entity', - 423 => 'Locked', - 424 => 'Failed Dependency', - 425 => 'Reserved for WebDAV advanced collections expired proposal', - 426 => 'Upgrade required', - 428 => 'Precondition Required', - 429 => 'Too Many Requests', - 431 => 'Request Header Fields Too Large', - 500 => 'Internal Server Error', - 501 => 'Not Implemented', - 502 => 'Bad Gateway', - 503 => 'Service Unavailable', - 504 => 'Gateway Timeout', - 505 => 'HTTP Version Not Supported', - 506 => 'Variant Also Negotiates (Experimental)', - 507 => 'Insufficient Storage', - 508 => 'Loop Detected', - 510 => 'Not Extended', - 511 => 'Network Authentication Required', - ); - - /** @var string The reason phrase of the response (human readable code) */ - private $reasonPhrase; - - /** @var string The status code of the response */ - private $statusCode; - - /** @var string The effective URL that returned this response */ - private $effectiveUrl; - - /** - * @param string $statusCode The response status code (e.g. 200) - * @param array $headers The response headers - * @param StreamInterface $body The body of the response - * @param array $options Response message options - * - reason_phrase: Set a custom reason phrase - * - protocol_version: Set a custom protocol version - */ - public function __construct( - $statusCode, - array $headers = [], - StreamInterface $body = null, - array $options = [] - ) { - $this->statusCode = (string) $statusCode; - $this->handleOptions($options); - - // Assume a reason phrase if one was not applied as an option - if (!$this->reasonPhrase && - isset(self::$statusTexts[$this->statusCode]) - ) { - $this->reasonPhrase = self::$statusTexts[$this->statusCode]; - } - - if ($headers) { - $this->setHeaders($headers); - } - - if ($body) { - $this->setBody($body); - } - } - - public function getStatusCode() - { - return $this->statusCode; - } - - public function getReasonPhrase() - { - return $this->reasonPhrase; - } - - public function json(array $config = []) - { - try { - return \GuzzleHttp\json_decode( - (string) $this->getBody(), - isset($config['object']) ? !$config['object'] : true, - 512, - isset($config['big_int_strings']) ? JSON_BIGINT_AS_STRING : 0 - ); - } catch (\InvalidArgumentException $e) { - throw new ParseException( - $e->getMessage(), - $this - ); - } - } - - public function xml(array $config = []) - { - $disableEntities = libxml_disable_entity_loader(true); - $internalErrors = libxml_use_internal_errors(true); - - try { - // Allow XML to be retrieved even if there is no response body - $xml = new \SimpleXMLElement( - (string) $this->getBody() ?: '', - LIBXML_NONET, - isset($config['ns']) ? $config['ns'] : '', - isset($config['ns_is_prefix']) ? $config['ns_is_prefix'] : false - ); - libxml_disable_entity_loader($disableEntities); - libxml_use_internal_errors($internalErrors); - } catch (\Exception $e) { - libxml_disable_entity_loader($disableEntities); - libxml_use_internal_errors($internalErrors); - throw new ParseException( - 'Unable to parse response body into XML: ' . $e->getMessage(), - $this - ); - } - - return $xml; - } - - public function getEffectiveUrl() - { - return $this->effectiveUrl; - } - - public function setEffectiveUrl($url) - { - $this->effectiveUrl = $url; - - return $this; - } - - /** - * Accepts and modifies the options provided to the response in the - * constructor. - * - * @param array $options Options array passed by reference. - */ - protected function handleOptions(array &$options = []) - { - parent::handleOptions($options); - if (isset($options['reason_phrase'])) { - $this->reasonPhrase = $options['reason_phrase']; - } - } - - protected function getStartLine() - { - return 'HTTP/' . $this->getProtocolVersion() - . " {$this->statusCode} {$this->reasonPhrase}"; - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Message/ResponseInterface.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Message/ResponseInterface.php deleted file mode 100644 index db8252c6b75f20a1f4abb47e28a6064195aac106..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Message/ResponseInterface.php +++ /dev/null @@ -1,86 +0,0 @@ - 'text/vnd.in3d.3dml', - '3g2' => 'video/3gpp2', - '3gp' => 'video/3gpp', - '7z' => 'application/x-7z-compressed', - 'aab' => 'application/x-authorware-bin', - 'aac' => 'audio/x-aac', - 'aam' => 'application/x-authorware-map', - 'aas' => 'application/x-authorware-seg', - 'abw' => 'application/x-abiword', - 'ac' => 'application/pkix-attr-cert', - 'acc' => 'application/vnd.americandynamics.acc', - 'ace' => 'application/x-ace-compressed', - 'acu' => 'application/vnd.acucobol', - 'acutc' => 'application/vnd.acucorp', - 'adp' => 'audio/adpcm', - 'aep' => 'application/vnd.audiograph', - 'afm' => 'application/x-font-type1', - 'afp' => 'application/vnd.ibm.modcap', - 'ahead' => 'application/vnd.ahead.space', - 'ai' => 'application/postscript', - 'aif' => 'audio/x-aiff', - 'aifc' => 'audio/x-aiff', - 'aiff' => 'audio/x-aiff', - 'air' => 'application/vnd.adobe.air-application-installer-package+zip', - 'ait' => 'application/vnd.dvb.ait', - 'ami' => 'application/vnd.amiga.ami', - 'apk' => 'application/vnd.android.package-archive', - 'application' => 'application/x-ms-application', - 'apr' => 'application/vnd.lotus-approach', - 'asa' => 'text/plain', - 'asax' => 'application/octet-stream', - 'asc' => 'application/pgp-signature', - 'ascx' => 'text/plain', - 'asf' => 'video/x-ms-asf', - 'ashx' => 'text/plain', - 'asm' => 'text/x-asm', - 'asmx' => 'text/plain', - 'aso' => 'application/vnd.accpac.simply.aso', - 'asp' => 'text/plain', - 'aspx' => 'text/plain', - 'asx' => 'video/x-ms-asf', - 'atc' => 'application/vnd.acucorp', - 'atom' => 'application/atom+xml', - 'atomcat' => 'application/atomcat+xml', - 'atomsvc' => 'application/atomsvc+xml', - 'atx' => 'application/vnd.antix.game-component', - 'au' => 'audio/basic', - 'avi' => 'video/x-msvideo', - 'aw' => 'application/applixware', - 'axd' => 'text/plain', - 'azf' => 'application/vnd.airzip.filesecure.azf', - 'azs' => 'application/vnd.airzip.filesecure.azs', - 'azw' => 'application/vnd.amazon.ebook', - 'bat' => 'application/x-msdownload', - 'bcpio' => 'application/x-bcpio', - 'bdf' => 'application/x-font-bdf', - 'bdm' => 'application/vnd.syncml.dm+wbxml', - 'bed' => 'application/vnd.realvnc.bed', - 'bh2' => 'application/vnd.fujitsu.oasysprs', - 'bin' => 'application/octet-stream', - 'bmi' => 'application/vnd.bmi', - 'bmp' => 'image/bmp', - 'book' => 'application/vnd.framemaker', - 'box' => 'application/vnd.previewsystems.box', - 'boz' => 'application/x-bzip2', - 'bpk' => 'application/octet-stream', - 'btif' => 'image/prs.btif', - 'bz' => 'application/x-bzip', - 'bz2' => 'application/x-bzip2', - 'c' => 'text/x-c', - 'c11amc' => 'application/vnd.cluetrust.cartomobile-config', - 'c11amz' => 'application/vnd.cluetrust.cartomobile-config-pkg', - 'c4d' => 'application/vnd.clonk.c4group', - 'c4f' => 'application/vnd.clonk.c4group', - 'c4g' => 'application/vnd.clonk.c4group', - 'c4p' => 'application/vnd.clonk.c4group', - 'c4u' => 'application/vnd.clonk.c4group', - 'cab' => 'application/vnd.ms-cab-compressed', - 'car' => 'application/vnd.curl.car', - 'cat' => 'application/vnd.ms-pki.seccat', - 'cc' => 'text/x-c', - 'cct' => 'application/x-director', - 'ccxml' => 'application/ccxml+xml', - 'cdbcmsg' => 'application/vnd.contact.cmsg', - 'cdf' => 'application/x-netcdf', - 'cdkey' => 'application/vnd.mediastation.cdkey', - 'cdmia' => 'application/cdmi-capability', - 'cdmic' => 'application/cdmi-container', - 'cdmid' => 'application/cdmi-domain', - 'cdmio' => 'application/cdmi-object', - 'cdmiq' => 'application/cdmi-queue', - 'cdx' => 'chemical/x-cdx', - 'cdxml' => 'application/vnd.chemdraw+xml', - 'cdy' => 'application/vnd.cinderella', - 'cer' => 'application/pkix-cert', - 'cfc' => 'application/x-coldfusion', - 'cfm' => 'application/x-coldfusion', - 'cgm' => 'image/cgm', - 'chat' => 'application/x-chat', - 'chm' => 'application/vnd.ms-htmlhelp', - 'chrt' => 'application/vnd.kde.kchart', - 'cif' => 'chemical/x-cif', - 'cii' => 'application/vnd.anser-web-certificate-issue-initiation', - 'cil' => 'application/vnd.ms-artgalry', - 'cla' => 'application/vnd.claymore', - 'class' => 'application/java-vm', - 'clkk' => 'application/vnd.crick.clicker.keyboard', - 'clkp' => 'application/vnd.crick.clicker.palette', - 'clkt' => 'application/vnd.crick.clicker.template', - 'clkw' => 'application/vnd.crick.clicker.wordbank', - 'clkx' => 'application/vnd.crick.clicker', - 'clp' => 'application/x-msclip', - 'cmc' => 'application/vnd.cosmocaller', - 'cmdf' => 'chemical/x-cmdf', - 'cml' => 'chemical/x-cml', - 'cmp' => 'application/vnd.yellowriver-custom-menu', - 'cmx' => 'image/x-cmx', - 'cod' => 'application/vnd.rim.cod', - 'com' => 'application/x-msdownload', - 'conf' => 'text/plain', - 'cpio' => 'application/x-cpio', - 'cpp' => 'text/x-c', - 'cpt' => 'application/mac-compactpro', - 'crd' => 'application/x-mscardfile', - 'crl' => 'application/pkix-crl', - 'crt' => 'application/x-x509-ca-cert', - 'cryptonote' => 'application/vnd.rig.cryptonote', - 'cs' => 'text/plain', - 'csh' => 'application/x-csh', - 'csml' => 'chemical/x-csml', - 'csp' => 'application/vnd.commonspace', - 'css' => 'text/css', - 'cst' => 'application/x-director', - 'csv' => 'text/csv', - 'cu' => 'application/cu-seeme', - 'curl' => 'text/vnd.curl', - 'cww' => 'application/prs.cww', - 'cxt' => 'application/x-director', - 'cxx' => 'text/x-c', - 'dae' => 'model/vnd.collada+xml', - 'daf' => 'application/vnd.mobius.daf', - 'dataless' => 'application/vnd.fdsn.seed', - 'davmount' => 'application/davmount+xml', - 'dcr' => 'application/x-director', - 'dcurl' => 'text/vnd.curl.dcurl', - 'dd2' => 'application/vnd.oma.dd2+xml', - 'ddd' => 'application/vnd.fujixerox.ddd', - 'deb' => 'application/x-debian-package', - 'def' => 'text/plain', - 'deploy' => 'application/octet-stream', - 'der' => 'application/x-x509-ca-cert', - 'dfac' => 'application/vnd.dreamfactory', - 'dic' => 'text/x-c', - 'dir' => 'application/x-director', - 'dis' => 'application/vnd.mobius.dis', - 'dist' => 'application/octet-stream', - 'distz' => 'application/octet-stream', - 'djv' => 'image/vnd.djvu', - 'djvu' => 'image/vnd.djvu', - 'dll' => 'application/x-msdownload', - 'dmg' => 'application/octet-stream', - 'dms' => 'application/octet-stream', - 'dna' => 'application/vnd.dna', - 'doc' => 'application/msword', - 'docm' => 'application/vnd.ms-word.document.macroenabled.12', - 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', - 'dot' => 'application/msword', - 'dotm' => 'application/vnd.ms-word.template.macroenabled.12', - 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', - 'dp' => 'application/vnd.osgi.dp', - 'dpg' => 'application/vnd.dpgraph', - 'dra' => 'audio/vnd.dra', - 'dsc' => 'text/prs.lines.tag', - 'dssc' => 'application/dssc+der', - 'dtb' => 'application/x-dtbook+xml', - 'dtd' => 'application/xml-dtd', - 'dts' => 'audio/vnd.dts', - 'dtshd' => 'audio/vnd.dts.hd', - 'dump' => 'application/octet-stream', - 'dvi' => 'application/x-dvi', - 'dwf' => 'model/vnd.dwf', - 'dwg' => 'image/vnd.dwg', - 'dxf' => 'image/vnd.dxf', - 'dxp' => 'application/vnd.spotfire.dxp', - 'dxr' => 'application/x-director', - 'ecelp4800' => 'audio/vnd.nuera.ecelp4800', - 'ecelp7470' => 'audio/vnd.nuera.ecelp7470', - 'ecelp9600' => 'audio/vnd.nuera.ecelp9600', - 'ecma' => 'application/ecmascript', - 'edm' => 'application/vnd.novadigm.edm', - 'edx' => 'application/vnd.novadigm.edx', - 'efif' => 'application/vnd.picsel', - 'ei6' => 'application/vnd.pg.osasli', - 'elc' => 'application/octet-stream', - 'eml' => 'message/rfc822', - 'emma' => 'application/emma+xml', - 'eol' => 'audio/vnd.digital-winds', - 'eot' => 'application/vnd.ms-fontobject', - 'eps' => 'application/postscript', - 'epub' => 'application/epub+zip', - 'es3' => 'application/vnd.eszigno3+xml', - 'esf' => 'application/vnd.epson.esf', - 'et3' => 'application/vnd.eszigno3+xml', - 'etx' => 'text/x-setext', - 'exe' => 'application/x-msdownload', - 'exi' => 'application/exi', - 'ext' => 'application/vnd.novadigm.ext', - 'ez' => 'application/andrew-inset', - 'ez2' => 'application/vnd.ezpix-album', - 'ez3' => 'application/vnd.ezpix-package', - 'f' => 'text/x-fortran', - 'f4v' => 'video/x-f4v', - 'f77' => 'text/x-fortran', - 'f90' => 'text/x-fortran', - 'fbs' => 'image/vnd.fastbidsheet', - 'fcs' => 'application/vnd.isac.fcs', - 'fdf' => 'application/vnd.fdf', - 'fe_launch' => 'application/vnd.denovo.fcselayout-link', - 'fg5' => 'application/vnd.fujitsu.oasysgp', - 'fgd' => 'application/x-director', - 'fh' => 'image/x-freehand', - 'fh4' => 'image/x-freehand', - 'fh5' => 'image/x-freehand', - 'fh7' => 'image/x-freehand', - 'fhc' => 'image/x-freehand', - 'fig' => 'application/x-xfig', - 'fli' => 'video/x-fli', - 'flo' => 'application/vnd.micrografx.flo', - 'flv' => 'video/x-flv', - 'flw' => 'application/vnd.kde.kivio', - 'flx' => 'text/vnd.fmi.flexstor', - 'fly' => 'text/vnd.fly', - 'fm' => 'application/vnd.framemaker', - 'fnc' => 'application/vnd.frogans.fnc', - 'for' => 'text/x-fortran', - 'fpx' => 'image/vnd.fpx', - 'frame' => 'application/vnd.framemaker', - 'fsc' => 'application/vnd.fsc.weblaunch', - 'fst' => 'image/vnd.fst', - 'ftc' => 'application/vnd.fluxtime.clip', - 'fti' => 'application/vnd.anser-web-funds-transfer-initiation', - 'fvt' => 'video/vnd.fvt', - 'fxp' => 'application/vnd.adobe.fxp', - 'fxpl' => 'application/vnd.adobe.fxp', - 'fzs' => 'application/vnd.fuzzysheet', - 'g2w' => 'application/vnd.geoplan', - 'g3' => 'image/g3fax', - 'g3w' => 'application/vnd.geospace', - 'gac' => 'application/vnd.groove-account', - 'gdl' => 'model/vnd.gdl', - 'geo' => 'application/vnd.dynageo', - 'gex' => 'application/vnd.geometry-explorer', - 'ggb' => 'application/vnd.geogebra.file', - 'ggt' => 'application/vnd.geogebra.tool', - 'ghf' => 'application/vnd.groove-help', - 'gif' => 'image/gif', - 'gim' => 'application/vnd.groove-identity-message', - 'gmx' => 'application/vnd.gmx', - 'gnumeric' => 'application/x-gnumeric', - 'gph' => 'application/vnd.flographit', - 'gqf' => 'application/vnd.grafeq', - 'gqs' => 'application/vnd.grafeq', - 'gram' => 'application/srgs', - 'gre' => 'application/vnd.geometry-explorer', - 'grv' => 'application/vnd.groove-injector', - 'grxml' => 'application/srgs+xml', - 'gsf' => 'application/x-font-ghostscript', - 'gtar' => 'application/x-gtar', - 'gtm' => 'application/vnd.groove-tool-message', - 'gtw' => 'model/vnd.gtw', - 'gv' => 'text/vnd.graphviz', - 'gxt' => 'application/vnd.geonext', - 'h' => 'text/x-c', - 'h261' => 'video/h261', - 'h263' => 'video/h263', - 'h264' => 'video/h264', - 'hal' => 'application/vnd.hal+xml', - 'hbci' => 'application/vnd.hbci', - 'hdf' => 'application/x-hdf', - 'hh' => 'text/x-c', - 'hlp' => 'application/winhlp', - 'hpgl' => 'application/vnd.hp-hpgl', - 'hpid' => 'application/vnd.hp-hpid', - 'hps' => 'application/vnd.hp-hps', - 'hqx' => 'application/mac-binhex40', - 'hta' => 'application/octet-stream', - 'htc' => 'text/html', - 'htke' => 'application/vnd.kenameaapp', - 'htm' => 'text/html', - 'html' => 'text/html', - 'hvd' => 'application/vnd.yamaha.hv-dic', - 'hvp' => 'application/vnd.yamaha.hv-voice', - 'hvs' => 'application/vnd.yamaha.hv-script', - 'i2g' => 'application/vnd.intergeo', - 'icc' => 'application/vnd.iccprofile', - 'ice' => 'x-conference/x-cooltalk', - 'icm' => 'application/vnd.iccprofile', - 'ico' => 'image/x-icon', - 'ics' => 'text/calendar', - 'ief' => 'image/ief', - 'ifb' => 'text/calendar', - 'ifm' => 'application/vnd.shana.informed.formdata', - 'iges' => 'model/iges', - 'igl' => 'application/vnd.igloader', - 'igm' => 'application/vnd.insors.igm', - 'igs' => 'model/iges', - 'igx' => 'application/vnd.micrografx.igx', - 'iif' => 'application/vnd.shana.informed.interchange', - 'imp' => 'application/vnd.accpac.simply.imp', - 'ims' => 'application/vnd.ms-ims', - 'in' => 'text/plain', - 'ini' => 'text/plain', - 'ipfix' => 'application/ipfix', - 'ipk' => 'application/vnd.shana.informed.package', - 'irm' => 'application/vnd.ibm.rights-management', - 'irp' => 'application/vnd.irepository.package+xml', - 'iso' => 'application/octet-stream', - 'itp' => 'application/vnd.shana.informed.formtemplate', - 'ivp' => 'application/vnd.immervision-ivp', - 'ivu' => 'application/vnd.immervision-ivu', - 'jad' => 'text/vnd.sun.j2me.app-descriptor', - 'jam' => 'application/vnd.jam', - 'jar' => 'application/java-archive', - 'java' => 'text/x-java-source', - 'jisp' => 'application/vnd.jisp', - 'jlt' => 'application/vnd.hp-jlyt', - 'jnlp' => 'application/x-java-jnlp-file', - 'joda' => 'application/vnd.joost.joda-archive', - 'jpe' => 'image/jpeg', - 'jpeg' => 'image/jpeg', - 'jpg' => 'image/jpeg', - 'jpgm' => 'video/jpm', - 'jpgv' => 'video/jpeg', - 'jpm' => 'video/jpm', - 'js' => 'text/javascript', - 'json' => 'application/json', - 'kar' => 'audio/midi', - 'karbon' => 'application/vnd.kde.karbon', - 'kfo' => 'application/vnd.kde.kformula', - 'kia' => 'application/vnd.kidspiration', - 'kml' => 'application/vnd.google-earth.kml+xml', - 'kmz' => 'application/vnd.google-earth.kmz', - 'kne' => 'application/vnd.kinar', - 'knp' => 'application/vnd.kinar', - 'kon' => 'application/vnd.kde.kontour', - 'kpr' => 'application/vnd.kde.kpresenter', - 'kpt' => 'application/vnd.kde.kpresenter', - 'ksp' => 'application/vnd.kde.kspread', - 'ktr' => 'application/vnd.kahootz', - 'ktx' => 'image/ktx', - 'ktz' => 'application/vnd.kahootz', - 'kwd' => 'application/vnd.kde.kword', - 'kwt' => 'application/vnd.kde.kword', - 'lasxml' => 'application/vnd.las.las+xml', - 'latex' => 'application/x-latex', - 'lbd' => 'application/vnd.llamagraphics.life-balance.desktop', - 'lbe' => 'application/vnd.llamagraphics.life-balance.exchange+xml', - 'les' => 'application/vnd.hhe.lesson-player', - 'lha' => 'application/octet-stream', - 'link66' => 'application/vnd.route66.link66+xml', - 'list' => 'text/plain', - 'list3820' => 'application/vnd.ibm.modcap', - 'listafp' => 'application/vnd.ibm.modcap', - 'log' => 'text/plain', - 'lostxml' => 'application/lost+xml', - 'lrf' => 'application/octet-stream', - 'lrm' => 'application/vnd.ms-lrm', - 'ltf' => 'application/vnd.frogans.ltf', - 'lvp' => 'audio/vnd.lucent.voice', - 'lwp' => 'application/vnd.lotus-wordpro', - 'lzh' => 'application/octet-stream', - 'm13' => 'application/x-msmediaview', - 'm14' => 'application/x-msmediaview', - 'm1v' => 'video/mpeg', - 'm21' => 'application/mp21', - 'm2a' => 'audio/mpeg', - 'm2v' => 'video/mpeg', - 'm3a' => 'audio/mpeg', - 'm3u' => 'audio/x-mpegurl', - 'm3u8' => 'application/vnd.apple.mpegurl', - 'm4a' => 'audio/mp4', - 'm4u' => 'video/vnd.mpegurl', - 'm4v' => 'video/mp4', - 'ma' => 'application/mathematica', - 'mads' => 'application/mads+xml', - 'mag' => 'application/vnd.ecowin.chart', - 'maker' => 'application/vnd.framemaker', - 'man' => 'text/troff', - 'mathml' => 'application/mathml+xml', - 'mb' => 'application/mathematica', - 'mbk' => 'application/vnd.mobius.mbk', - 'mbox' => 'application/mbox', - 'mc1' => 'application/vnd.medcalcdata', - 'mcd' => 'application/vnd.mcd', - 'mcurl' => 'text/vnd.curl.mcurl', - 'mdb' => 'application/x-msaccess', - 'mdi' => 'image/vnd.ms-modi', - 'me' => 'text/troff', - 'mesh' => 'model/mesh', - 'meta4' => 'application/metalink4+xml', - 'mets' => 'application/mets+xml', - 'mfm' => 'application/vnd.mfmp', - 'mgp' => 'application/vnd.osgeo.mapguide.package', - 'mgz' => 'application/vnd.proteus.magazine', - 'mid' => 'audio/midi', - 'midi' => 'audio/midi', - 'mif' => 'application/vnd.mif', - 'mime' => 'message/rfc822', - 'mj2' => 'video/mj2', - 'mjp2' => 'video/mj2', - 'mlp' => 'application/vnd.dolby.mlp', - 'mmd' => 'application/vnd.chipnuts.karaoke-mmd', - 'mmf' => 'application/vnd.smaf', - 'mmr' => 'image/vnd.fujixerox.edmics-mmr', - 'mny' => 'application/x-msmoney', - 'mobi' => 'application/x-mobipocket-ebook', - 'mods' => 'application/mods+xml', - 'mov' => 'video/quicktime', - 'movie' => 'video/x-sgi-movie', - 'mp2' => 'audio/mpeg', - 'mp21' => 'application/mp21', - 'mp2a' => 'audio/mpeg', - 'mp3' => 'audio/mpeg', - 'mp4' => 'video/mp4', - 'mp4a' => 'audio/mp4', - 'mp4s' => 'application/mp4', - 'mp4v' => 'video/mp4', - 'mpc' => 'application/vnd.mophun.certificate', - 'mpe' => 'video/mpeg', - 'mpeg' => 'video/mpeg', - 'mpg' => 'video/mpeg', - 'mpg4' => 'video/mp4', - 'mpga' => 'audio/mpeg', - 'mpkg' => 'application/vnd.apple.installer+xml', - 'mpm' => 'application/vnd.blueice.multipass', - 'mpn' => 'application/vnd.mophun.application', - 'mpp' => 'application/vnd.ms-project', - 'mpt' => 'application/vnd.ms-project', - 'mpy' => 'application/vnd.ibm.minipay', - 'mqy' => 'application/vnd.mobius.mqy', - 'mrc' => 'application/marc', - 'mrcx' => 'application/marcxml+xml', - 'ms' => 'text/troff', - 'mscml' => 'application/mediaservercontrol+xml', - 'mseed' => 'application/vnd.fdsn.mseed', - 'mseq' => 'application/vnd.mseq', - 'msf' => 'application/vnd.epson.msf', - 'msh' => 'model/mesh', - 'msi' => 'application/x-msdownload', - 'msl' => 'application/vnd.mobius.msl', - 'msty' => 'application/vnd.muvee.style', - 'mts' => 'model/vnd.mts', - 'mus' => 'application/vnd.musician', - 'musicxml' => 'application/vnd.recordare.musicxml+xml', - 'mvb' => 'application/x-msmediaview', - 'mwf' => 'application/vnd.mfer', - 'mxf' => 'application/mxf', - 'mxl' => 'application/vnd.recordare.musicxml', - 'mxml' => 'application/xv+xml', - 'mxs' => 'application/vnd.triscape.mxs', - 'mxu' => 'video/vnd.mpegurl', - 'n-gage' => 'application/vnd.nokia.n-gage.symbian.install', - 'n3' => 'text/n3', - 'nb' => 'application/mathematica', - 'nbp' => 'application/vnd.wolfram.player', - 'nc' => 'application/x-netcdf', - 'ncx' => 'application/x-dtbncx+xml', - 'ngdat' => 'application/vnd.nokia.n-gage.data', - 'nlu' => 'application/vnd.neurolanguage.nlu', - 'nml' => 'application/vnd.enliven', - 'nnd' => 'application/vnd.noblenet-directory', - 'nns' => 'application/vnd.noblenet-sealer', - 'nnw' => 'application/vnd.noblenet-web', - 'npx' => 'image/vnd.net-fpx', - 'nsf' => 'application/vnd.lotus-notes', - 'oa2' => 'application/vnd.fujitsu.oasys2', - 'oa3' => 'application/vnd.fujitsu.oasys3', - 'oas' => 'application/vnd.fujitsu.oasys', - 'obd' => 'application/x-msbinder', - 'oda' => 'application/oda', - 'odb' => 'application/vnd.oasis.opendocument.database', - 'odc' => 'application/vnd.oasis.opendocument.chart', - 'odf' => 'application/vnd.oasis.opendocument.formula', - 'odft' => 'application/vnd.oasis.opendocument.formula-template', - 'odg' => 'application/vnd.oasis.opendocument.graphics', - 'odi' => 'application/vnd.oasis.opendocument.image', - 'odm' => 'application/vnd.oasis.opendocument.text-master', - 'odp' => 'application/vnd.oasis.opendocument.presentation', - 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', - 'odt' => 'application/vnd.oasis.opendocument.text', - 'oga' => 'audio/ogg', - 'ogg' => 'audio/ogg', - 'ogv' => 'video/ogg', - 'ogx' => 'application/ogg', - 'onepkg' => 'application/onenote', - 'onetmp' => 'application/onenote', - 'onetoc' => 'application/onenote', - 'onetoc2' => 'application/onenote', - 'opf' => 'application/oebps-package+xml', - 'oprc' => 'application/vnd.palm', - 'org' => 'application/vnd.lotus-organizer', - 'osf' => 'application/vnd.yamaha.openscoreformat', - 'osfpvg' => 'application/vnd.yamaha.openscoreformat.osfpvg+xml', - 'otc' => 'application/vnd.oasis.opendocument.chart-template', - 'otf' => 'application/x-font-otf', - 'otg' => 'application/vnd.oasis.opendocument.graphics-template', - 'oth' => 'application/vnd.oasis.opendocument.text-web', - 'oti' => 'application/vnd.oasis.opendocument.image-template', - 'otp' => 'application/vnd.oasis.opendocument.presentation-template', - 'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template', - 'ott' => 'application/vnd.oasis.opendocument.text-template', - 'oxt' => 'application/vnd.openofficeorg.extension', - 'p' => 'text/x-pascal', - 'p10' => 'application/pkcs10', - 'p12' => 'application/x-pkcs12', - 'p7b' => 'application/x-pkcs7-certificates', - 'p7c' => 'application/pkcs7-mime', - 'p7m' => 'application/pkcs7-mime', - 'p7r' => 'application/x-pkcs7-certreqresp', - 'p7s' => 'application/pkcs7-signature', - 'p8' => 'application/pkcs8', - 'pas' => 'text/x-pascal', - 'paw' => 'application/vnd.pawaafile', - 'pbd' => 'application/vnd.powerbuilder6', - 'pbm' => 'image/x-portable-bitmap', - 'pcf' => 'application/x-font-pcf', - 'pcl' => 'application/vnd.hp-pcl', - 'pclxl' => 'application/vnd.hp-pclxl', - 'pct' => 'image/x-pict', - 'pcurl' => 'application/vnd.curl.pcurl', - 'pcx' => 'image/x-pcx', - 'pdb' => 'application/vnd.palm', - 'pdf' => 'application/pdf', - 'pfa' => 'application/x-font-type1', - 'pfb' => 'application/x-font-type1', - 'pfm' => 'application/x-font-type1', - 'pfr' => 'application/font-tdpfr', - 'pfx' => 'application/x-pkcs12', - 'pgm' => 'image/x-portable-graymap', - 'pgn' => 'application/x-chess-pgn', - 'pgp' => 'application/pgp-encrypted', - 'php' => 'text/x-php', - 'phps' => 'application/x-httpd-phps', - 'pic' => 'image/x-pict', - 'pkg' => 'application/octet-stream', - 'pki' => 'application/pkixcmp', - 'pkipath' => 'application/pkix-pkipath', - 'plb' => 'application/vnd.3gpp.pic-bw-large', - 'plc' => 'application/vnd.mobius.plc', - 'plf' => 'application/vnd.pocketlearn', - 'pls' => 'application/pls+xml', - 'pml' => 'application/vnd.ctc-posml', - 'png' => 'image/png', - 'pnm' => 'image/x-portable-anymap', - 'portpkg' => 'application/vnd.macports.portpkg', - 'pot' => 'application/vnd.ms-powerpoint', - 'potm' => 'application/vnd.ms-powerpoint.template.macroenabled.12', - 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template', - 'ppam' => 'application/vnd.ms-powerpoint.addin.macroenabled.12', - 'ppd' => 'application/vnd.cups-ppd', - 'ppm' => 'image/x-portable-pixmap', - 'pps' => 'application/vnd.ms-powerpoint', - 'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroenabled.12', - 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', - 'ppt' => 'application/vnd.ms-powerpoint', - 'pptm' => 'application/vnd.ms-powerpoint.presentation.macroenabled.12', - 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', - 'pqa' => 'application/vnd.palm', - 'prc' => 'application/x-mobipocket-ebook', - 'pre' => 'application/vnd.lotus-freelance', - 'prf' => 'application/pics-rules', - 'ps' => 'application/postscript', - 'psb' => 'application/vnd.3gpp.pic-bw-small', - 'psd' => 'image/vnd.adobe.photoshop', - 'psf' => 'application/x-font-linux-psf', - 'pskcxml' => 'application/pskc+xml', - 'ptid' => 'application/vnd.pvi.ptid1', - 'pub' => 'application/x-mspublisher', - 'pvb' => 'application/vnd.3gpp.pic-bw-var', - 'pwn' => 'application/vnd.3m.post-it-notes', - 'pya' => 'audio/vnd.ms-playready.media.pya', - 'pyv' => 'video/vnd.ms-playready.media.pyv', - 'qam' => 'application/vnd.epson.quickanime', - 'qbo' => 'application/vnd.intu.qbo', - 'qfx' => 'application/vnd.intu.qfx', - 'qps' => 'application/vnd.publishare-delta-tree', - 'qt' => 'video/quicktime', - 'qwd' => 'application/vnd.quark.quarkxpress', - 'qwt' => 'application/vnd.quark.quarkxpress', - 'qxb' => 'application/vnd.quark.quarkxpress', - 'qxd' => 'application/vnd.quark.quarkxpress', - 'qxl' => 'application/vnd.quark.quarkxpress', - 'qxt' => 'application/vnd.quark.quarkxpress', - 'ra' => 'audio/x-pn-realaudio', - 'ram' => 'audio/x-pn-realaudio', - 'rar' => 'application/x-rar-compressed', - 'ras' => 'image/x-cmu-raster', - 'rb' => 'text/plain', - 'rcprofile' => 'application/vnd.ipunplugged.rcprofile', - 'rdf' => 'application/rdf+xml', - 'rdz' => 'application/vnd.data-vision.rdz', - 'rep' => 'application/vnd.businessobjects', - 'res' => 'application/x-dtbresource+xml', - 'resx' => 'text/xml', - 'rgb' => 'image/x-rgb', - 'rif' => 'application/reginfo+xml', - 'rip' => 'audio/vnd.rip', - 'rl' => 'application/resource-lists+xml', - 'rlc' => 'image/vnd.fujixerox.edmics-rlc', - 'rld' => 'application/resource-lists-diff+xml', - 'rm' => 'application/vnd.rn-realmedia', - 'rmi' => 'audio/midi', - 'rmp' => 'audio/x-pn-realaudio-plugin', - 'rms' => 'application/vnd.jcp.javame.midlet-rms', - 'rnc' => 'application/relax-ng-compact-syntax', - 'roff' => 'text/troff', - 'rp9' => 'application/vnd.cloanto.rp9', - 'rpss' => 'application/vnd.nokia.radio-presets', - 'rpst' => 'application/vnd.nokia.radio-preset', - 'rq' => 'application/sparql-query', - 'rs' => 'application/rls-services+xml', - 'rsd' => 'application/rsd+xml', - 'rss' => 'application/rss+xml', - 'rtf' => 'application/rtf', - 'rtx' => 'text/richtext', - 's' => 'text/x-asm', - 'saf' => 'application/vnd.yamaha.smaf-audio', - 'sbml' => 'application/sbml+xml', - 'sc' => 'application/vnd.ibm.secure-container', - 'scd' => 'application/x-msschedule', - 'scm' => 'application/vnd.lotus-screencam', - 'scq' => 'application/scvp-cv-request', - 'scs' => 'application/scvp-cv-response', - 'scurl' => 'text/vnd.curl.scurl', - 'sda' => 'application/vnd.stardivision.draw', - 'sdc' => 'application/vnd.stardivision.calc', - 'sdd' => 'application/vnd.stardivision.impress', - 'sdkd' => 'application/vnd.solent.sdkm+xml', - 'sdkm' => 'application/vnd.solent.sdkm+xml', - 'sdp' => 'application/sdp', - 'sdw' => 'application/vnd.stardivision.writer', - 'see' => 'application/vnd.seemail', - 'seed' => 'application/vnd.fdsn.seed', - 'sema' => 'application/vnd.sema', - 'semd' => 'application/vnd.semd', - 'semf' => 'application/vnd.semf', - 'ser' => 'application/java-serialized-object', - 'setpay' => 'application/set-payment-initiation', - 'setreg' => 'application/set-registration-initiation', - 'sfd-hdstx' => 'application/vnd.hydrostatix.sof-data', - 'sfs' => 'application/vnd.spotfire.sfs', - 'sgl' => 'application/vnd.stardivision.writer-global', - 'sgm' => 'text/sgml', - 'sgml' => 'text/sgml', - 'sh' => 'application/x-sh', - 'shar' => 'application/x-shar', - 'shf' => 'application/shf+xml', - 'sig' => 'application/pgp-signature', - 'silo' => 'model/mesh', - 'sis' => 'application/vnd.symbian.install', - 'sisx' => 'application/vnd.symbian.install', - 'sit' => 'application/x-stuffit', - 'sitx' => 'application/x-stuffitx', - 'skd' => 'application/vnd.koan', - 'skm' => 'application/vnd.koan', - 'skp' => 'application/vnd.koan', - 'skt' => 'application/vnd.koan', - 'sldm' => 'application/vnd.ms-powerpoint.slide.macroenabled.12', - 'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide', - 'slt' => 'application/vnd.epson.salt', - 'sm' => 'application/vnd.stepmania.stepchart', - 'smf' => 'application/vnd.stardivision.math', - 'smi' => 'application/smil+xml', - 'smil' => 'application/smil+xml', - 'snd' => 'audio/basic', - 'snf' => 'application/x-font-snf', - 'so' => 'application/octet-stream', - 'spc' => 'application/x-pkcs7-certificates', - 'spf' => 'application/vnd.yamaha.smaf-phrase', - 'spl' => 'application/x-futuresplash', - 'spot' => 'text/vnd.in3d.spot', - 'spp' => 'application/scvp-vp-response', - 'spq' => 'application/scvp-vp-request', - 'spx' => 'audio/ogg', - 'src' => 'application/x-wais-source', - 'sru' => 'application/sru+xml', - 'srx' => 'application/sparql-results+xml', - 'sse' => 'application/vnd.kodak-descriptor', - 'ssf' => 'application/vnd.epson.ssf', - 'ssml' => 'application/ssml+xml', - 'st' => 'application/vnd.sailingtracker.track', - 'stc' => 'application/vnd.sun.xml.calc.template', - 'std' => 'application/vnd.sun.xml.draw.template', - 'stf' => 'application/vnd.wt.stf', - 'sti' => 'application/vnd.sun.xml.impress.template', - 'stk' => 'application/hyperstudio', - 'stl' => 'application/vnd.ms-pki.stl', - 'str' => 'application/vnd.pg.format', - 'stw' => 'application/vnd.sun.xml.writer.template', - 'sub' => 'image/vnd.dvb.subtitle', - 'sus' => 'application/vnd.sus-calendar', - 'susp' => 'application/vnd.sus-calendar', - 'sv4cpio' => 'application/x-sv4cpio', - 'sv4crc' => 'application/x-sv4crc', - 'svc' => 'application/vnd.dvb.service', - 'svd' => 'application/vnd.svd', - 'svg' => 'image/svg+xml', - 'svgz' => 'image/svg+xml', - 'swa' => 'application/x-director', - 'swf' => 'application/x-shockwave-flash', - 'swi' => 'application/vnd.aristanetworks.swi', - 'sxc' => 'application/vnd.sun.xml.calc', - 'sxd' => 'application/vnd.sun.xml.draw', - 'sxg' => 'application/vnd.sun.xml.writer.global', - 'sxi' => 'application/vnd.sun.xml.impress', - 'sxm' => 'application/vnd.sun.xml.math', - 'sxw' => 'application/vnd.sun.xml.writer', - 't' => 'text/troff', - 'tao' => 'application/vnd.tao.intent-module-archive', - 'tar' => 'application/x-tar', - 'tcap' => 'application/vnd.3gpp2.tcap', - 'tcl' => 'application/x-tcl', - 'teacher' => 'application/vnd.smart.teacher', - 'tei' => 'application/tei+xml', - 'teicorpus' => 'application/tei+xml', - 'tex' => 'application/x-tex', - 'texi' => 'application/x-texinfo', - 'texinfo' => 'application/x-texinfo', - 'text' => 'text/plain', - 'tfi' => 'application/thraud+xml', - 'tfm' => 'application/x-tex-tfm', - 'thmx' => 'application/vnd.ms-officetheme', - 'tif' => 'image/tiff', - 'tiff' => 'image/tiff', - 'tmo' => 'application/vnd.tmobile-livetv', - 'torrent' => 'application/x-bittorrent', - 'tpl' => 'application/vnd.groove-tool-template', - 'tpt' => 'application/vnd.trid.tpt', - 'tr' => 'text/troff', - 'tra' => 'application/vnd.trueapp', - 'trm' => 'application/x-msterminal', - 'tsd' => 'application/timestamped-data', - 'tsv' => 'text/tab-separated-values', - 'ttc' => 'application/x-font-ttf', - 'ttf' => 'application/x-font-ttf', - 'ttl' => 'text/turtle', - 'twd' => 'application/vnd.simtech-mindmapper', - 'twds' => 'application/vnd.simtech-mindmapper', - 'txd' => 'application/vnd.genomatix.tuxedo', - 'txf' => 'application/vnd.mobius.txf', - 'txt' => 'text/plain', - 'u32' => 'application/x-authorware-bin', - 'udeb' => 'application/x-debian-package', - 'ufd' => 'application/vnd.ufdl', - 'ufdl' => 'application/vnd.ufdl', - 'umj' => 'application/vnd.umajin', - 'unityweb' => 'application/vnd.unity', - 'uoml' => 'application/vnd.uoml+xml', - 'uri' => 'text/uri-list', - 'uris' => 'text/uri-list', - 'urls' => 'text/uri-list', - 'ustar' => 'application/x-ustar', - 'utz' => 'application/vnd.uiq.theme', - 'uu' => 'text/x-uuencode', - 'uva' => 'audio/vnd.dece.audio', - 'uvd' => 'application/vnd.dece.data', - 'uvf' => 'application/vnd.dece.data', - 'uvg' => 'image/vnd.dece.graphic', - 'uvh' => 'video/vnd.dece.hd', - 'uvi' => 'image/vnd.dece.graphic', - 'uvm' => 'video/vnd.dece.mobile', - 'uvp' => 'video/vnd.dece.pd', - 'uvs' => 'video/vnd.dece.sd', - 'uvt' => 'application/vnd.dece.ttml+xml', - 'uvu' => 'video/vnd.uvvu.mp4', - 'uvv' => 'video/vnd.dece.video', - 'uvva' => 'audio/vnd.dece.audio', - 'uvvd' => 'application/vnd.dece.data', - 'uvvf' => 'application/vnd.dece.data', - 'uvvg' => 'image/vnd.dece.graphic', - 'uvvh' => 'video/vnd.dece.hd', - 'uvvi' => 'image/vnd.dece.graphic', - 'uvvm' => 'video/vnd.dece.mobile', - 'uvvp' => 'video/vnd.dece.pd', - 'uvvs' => 'video/vnd.dece.sd', - 'uvvt' => 'application/vnd.dece.ttml+xml', - 'uvvu' => 'video/vnd.uvvu.mp4', - 'uvvv' => 'video/vnd.dece.video', - 'uvvx' => 'application/vnd.dece.unspecified', - 'uvx' => 'application/vnd.dece.unspecified', - 'vcd' => 'application/x-cdlink', - 'vcf' => 'text/x-vcard', - 'vcg' => 'application/vnd.groove-vcard', - 'vcs' => 'text/x-vcalendar', - 'vcx' => 'application/vnd.vcx', - 'vis' => 'application/vnd.visionary', - 'viv' => 'video/vnd.vivo', - 'vor' => 'application/vnd.stardivision.writer', - 'vox' => 'application/x-authorware-bin', - 'vrml' => 'model/vrml', - 'vsd' => 'application/vnd.visio', - 'vsf' => 'application/vnd.vsf', - 'vss' => 'application/vnd.visio', - 'vst' => 'application/vnd.visio', - 'vsw' => 'application/vnd.visio', - 'vtu' => 'model/vnd.vtu', - 'vxml' => 'application/voicexml+xml', - 'w3d' => 'application/x-director', - 'wad' => 'application/x-doom', - 'wav' => 'audio/x-wav', - 'wax' => 'audio/x-ms-wax', - 'wbmp' => 'image/vnd.wap.wbmp', - 'wbs' => 'application/vnd.criticaltools.wbs+xml', - 'wbxml' => 'application/vnd.wap.wbxml', - 'wcm' => 'application/vnd.ms-works', - 'wdb' => 'application/vnd.ms-works', - 'weba' => 'audio/webm', - 'webm' => 'video/webm', - 'webp' => 'image/webp', - 'wg' => 'application/vnd.pmi.widget', - 'wgt' => 'application/widget', - 'wks' => 'application/vnd.ms-works', - 'wm' => 'video/x-ms-wm', - 'wma' => 'audio/x-ms-wma', - 'wmd' => 'application/x-ms-wmd', - 'wmf' => 'application/x-msmetafile', - 'wml' => 'text/vnd.wap.wml', - 'wmlc' => 'application/vnd.wap.wmlc', - 'wmls' => 'text/vnd.wap.wmlscript', - 'wmlsc' => 'application/vnd.wap.wmlscriptc', - 'wmv' => 'video/x-ms-wmv', - 'wmx' => 'video/x-ms-wmx', - 'wmz' => 'application/x-ms-wmz', - 'woff' => 'application/x-font-woff', - 'wpd' => 'application/vnd.wordperfect', - 'wpl' => 'application/vnd.ms-wpl', - 'wps' => 'application/vnd.ms-works', - 'wqd' => 'application/vnd.wqd', - 'wri' => 'application/x-mswrite', - 'wrl' => 'model/vrml', - 'wsdl' => 'application/wsdl+xml', - 'wspolicy' => 'application/wspolicy+xml', - 'wtb' => 'application/vnd.webturbo', - 'wvx' => 'video/x-ms-wvx', - 'x32' => 'application/x-authorware-bin', - 'x3d' => 'application/vnd.hzn-3d-crossword', - 'xap' => 'application/x-silverlight-app', - 'xar' => 'application/vnd.xara', - 'xbap' => 'application/x-ms-xbap', - 'xbd' => 'application/vnd.fujixerox.docuworks.binder', - 'xbm' => 'image/x-xbitmap', - 'xdf' => 'application/xcap-diff+xml', - 'xdm' => 'application/vnd.syncml.dm+xml', - 'xdp' => 'application/vnd.adobe.xdp+xml', - 'xdssc' => 'application/dssc+xml', - 'xdw' => 'application/vnd.fujixerox.docuworks', - 'xenc' => 'application/xenc+xml', - 'xer' => 'application/patch-ops-error+xml', - 'xfdf' => 'application/vnd.adobe.xfdf', - 'xfdl' => 'application/vnd.xfdl', - 'xht' => 'application/xhtml+xml', - 'xhtml' => 'application/xhtml+xml', - 'xhvml' => 'application/xv+xml', - 'xif' => 'image/vnd.xiff', - 'xla' => 'application/vnd.ms-excel', - 'xlam' => 'application/vnd.ms-excel.addin.macroenabled.12', - 'xlc' => 'application/vnd.ms-excel', - 'xlm' => 'application/vnd.ms-excel', - 'xls' => 'application/vnd.ms-excel', - 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroenabled.12', - 'xlsm' => 'application/vnd.ms-excel.sheet.macroenabled.12', - 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', - 'xlt' => 'application/vnd.ms-excel', - 'xltm' => 'application/vnd.ms-excel.template.macroenabled.12', - 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', - 'xlw' => 'application/vnd.ms-excel', - 'xml' => 'application/xml', - 'xo' => 'application/vnd.olpc-sugar', - 'xop' => 'application/xop+xml', - 'xpi' => 'application/x-xpinstall', - 'xpm' => 'image/x-xpixmap', - 'xpr' => 'application/vnd.is-xpr', - 'xps' => 'application/vnd.ms-xpsdocument', - 'xpw' => 'application/vnd.intercon.formnet', - 'xpx' => 'application/vnd.intercon.formnet', - 'xsl' => 'application/xml', - 'xslt' => 'application/xslt+xml', - 'xsm' => 'application/vnd.syncml+xml', - 'xspf' => 'application/xspf+xml', - 'xul' => 'application/vnd.mozilla.xul+xml', - 'xvm' => 'application/xv+xml', - 'xvml' => 'application/xv+xml', - 'xwd' => 'image/x-xwindowdump', - 'xyz' => 'chemical/x-xyz', - 'yaml' => 'text/yaml', - 'yang' => 'application/yang', - 'yin' => 'application/yin+xml', - 'yml' => 'text/yaml', - 'zaz' => 'application/vnd.zzazz.deck+xml', - 'zip' => 'application/zip', - 'zir' => 'application/vnd.zul', - 'zirz' => 'application/vnd.zul', - 'zmm' => 'application/vnd.handheld-entertainment+xml' - ); - - /** - * Get a singleton instance of the class - * - * @return self - * @codeCoverageIgnore - */ - public static function getInstance() - { - if (!self::$instance) { - self::$instance = new self(); - } - - return self::$instance; - } - - /** - * Get a mimetype value from a file extension - * - * @param string $extension File extension - * - * @return string|null - * - */ - public function fromExtension($extension) - { - $extension = strtolower($extension); - - return isset($this->mimetypes[$extension]) - ? $this->mimetypes[$extension] - : null; - } - - /** - * Get a mimetype from a filename - * - * @param string $filename Filename to generate a mimetype from - * - * @return string|null - */ - public function fromFilename($filename) - { - return $this->fromExtension(pathinfo($filename, PATHINFO_EXTENSION)); - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Post/MultipartBody.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Post/MultipartBody.php deleted file mode 100644 index 72ce6e12c0fbede445105dc8d3353182a19803b1..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Post/MultipartBody.php +++ /dev/null @@ -1,292 +0,0 @@ -boundary = $boundary ?: uniqid(); - $this->fields = $fields; - $this->files = $files; - - // Ensure each file is a PostFileInterface - foreach ($this->files as $file) { - if (!$file instanceof PostFileInterface) { - throw new \InvalidArgumentException('All POST fields must ' - . 'implement PostFieldInterface'); - } - } - } - - public function __toString() - { - $this->seek(0); - - return $this->getContents(); - } - - public function getContents($maxLength = -1) - { - $buffer = ''; - - while (!$this->eof()) { - if ($maxLength === -1) { - $read = 1048576; - } else { - $len = strlen($buffer); - if ($len == $maxLength) { - break; - } - $read = min(1048576, $maxLength - $len); - } - $buffer .= $this->read($read); - } - - return $buffer; - } - - /** - * Get the boundary - * - * @return string - */ - public function getBoundary() - { - return $this->boundary; - } - - public function close() - { - $this->detach(); - } - - public function detach() - { - $this->fields = $this->files = []; - } - - /** - * The stream has reached an EOF when all of the fields and files have been - * read. - * {@inheritdoc} - */ - public function eof() - { - return $this->currentField == count($this->fields) && - $this->currentFile == count($this->files); - } - - public function tell() - { - return $this->pos; - } - - public function isReadable() - { - return true; - } - - public function isWritable() - { - return false; - } - - /** - * The steam is seekable by default, but all attached files must be - * seekable too. - * {@inheritdoc} - */ - public function isSeekable() - { - foreach ($this->files as $file) { - if (!$file->getContent()->isSeekable()) { - return false; - } - } - - return true; - } - - public function getSize() - { - if ($this->size === null) { - foreach ($this->files as $file) { - // We must be able to ascertain the size of each attached file - if (null === ($size = $file->getContent()->getSize())) { - return null; - } - $this->size += strlen($this->getFileHeaders($file)) + $size; - } - foreach (array_keys($this->fields) as $key) { - $this->size += strlen($this->getFieldString($key)); - } - $this->size += strlen("\r\n--{$this->boundary}--"); - } - - return $this->size; - } - - public function read($length) - { - $content = ''; - if ($this->buffer && !$this->buffer->eof()) { - $content .= $this->buffer->read($length); - } - if ($delta = $length - strlen($content)) { - $content .= $this->readData($delta); - } - - if ($content === '' && !$this->sentLast) { - $this->sentLast = true; - $content = "\r\n--{$this->boundary}--"; - } - - return $content; - } - - public function seek($offset, $whence = SEEK_SET) - { - if ($offset != 0 || $whence != SEEK_SET || !$this->isSeekable()) { - return false; - } - - foreach ($this->files as $file) { - if (!$file->getContent()->seek(0)) { - throw new \RuntimeException('Rewind on multipart file failed ' - . 'even though it shouldn\'t have'); - } - } - - $this->buffer = $this->sentLast = null; - $this->pos = $this->currentField = $this->currentFile = 0; - $this->bufferedHeaders = []; - - return true; - } - - public function write($string) - { - return false; - } - - /** - * No data is in the read buffer, so more needs to be pulled in from fields - * and files. - * - * @param int $length Amount of data to read - * - * @return string - */ - private function readData($length) - { - $result = ''; - - if ($this->currentField < count($this->fields)) { - $result = $this->readField($length); - } - - if ($result === '' && $this->currentFile < count($this->files)) { - $result = $this->readFile($length); - } - - return $result; - } - - /** - * Create a new stream buffer and inject form-data - * - * @param int $length Amount of data to read from the stream buffer - * - * @return string - */ - private function readField($length) - { - $name = array_keys($this->fields)[++$this->currentField - 1]; - $this->buffer = Stream\create($this->getFieldString($name)); - - return $this->buffer->read($length); - } - - /** - * Read data from a POST file, fill the read buffer with any overflow - * - * @param int $length Amount of data to read from the file - * - * @return string - */ - private function readFile($length) - { - $current = $this->files[$this->currentFile]; - - // Got to the next file and recursively return the read value, or bail - // if no more data can be read. - if ($current->getContent()->eof()) { - return ++$this->currentFile == count($this->files) - ? '' - : $this->readFile($length); - } - - // If this is the start of a file, then send the headers to the read - // buffer. - if (!isset($this->bufferedHeaders[$this->currentFile])) { - $this->buffer = Stream\create($this->getFileHeaders($current)); - $this->bufferedHeaders[$this->currentFile] = true; - } - - // More data needs to be read to meet the limit, so pull from the file - $content = $this->buffer ? $this->buffer->read($length) : ''; - if (($remaining = $length - strlen($content)) > 0) { - $content .= $current->getContent()->read($remaining); - } - - return $content; - } - - private function getFieldString($key) - { - return sprintf( - "--%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n%s\r\n", - $this->boundary, - $key, - $this->fields[$key] - ); - } - - private function getFileHeaders(PostFileInterface $file) - { - $headers = ''; - foreach ($file->getHeaders() as $key => $value) { - $headers .= "{$key}: {$value}\r\n"; - } - - return "--{$this->boundary}\r\n" . trim($headers) . "\r\n\r\n"; - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Post/PostBody.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Post/PostBody.php deleted file mode 100644 index 6ba253be17c9bb714ce0dc8505f85a22ee59feaf..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Post/PostBody.php +++ /dev/null @@ -1,282 +0,0 @@ -files || $this->forceMultipart) { - $request->setHeader( - 'Content-Type', - 'multipart/form-data; boundary=' . $this->getBody()->getBoundary() - ); - } elseif ($this->fields) { - $request->setHeader('Content-Type', 'application/x-www-form-urlencoded'); - } - - if ($size = $this->getSize()) { - $request->setHeader('Content-Length', $size); - } - } - - public function forceMultipartUpload($force) - { - $this->forceMultipart = $force; - - return $this; - } - - public function setAggregator(callable $aggregator) - { - $this->aggregator = $aggregator; - } - - public function setField($name, $value) - { - $this->fields[$name] = $value; - $this->mutate(); - - return $this; - } - - public function replaceFields(array $fields) - { - $this->fields = $fields; - $this->mutate(); - - return $this; - } - - public function getField($name) - { - return isset($this->fields[$name]) ? $this->fields[$name] : null; - } - - public function removeField($name) - { - unset($this->fields[$name]); - $this->mutate(); - - return $this; - } - - public function getFields($asString = false) - { - if (!$asString) { - return $this->fields; - } - - return (string) (new Query($this->fields)) - ->setEncodingType(Query::RFC1738) - ->setAggregator($this->getAggregator()); - } - - public function hasField($name) - { - return isset($this->fields[$name]); - } - - public function getFile($name) - { - foreach ($this->files as $file) { - if ($file->getName() == $name) { - return $file; - } - } - - return null; - } - - public function getFiles() - { - return $this->files; - } - - public function addFile(PostFileInterface $file) - { - $this->files[] = $file; - $this->mutate(); - - return $this; - } - - public function clearFiles() - { - $this->files = []; - $this->mutate(); - - return $this; - } - - /** - * Returns the numbers of fields + files - * - * @return int - */ - public function count() - { - return count($this->files) + count($this->fields); - } - - public function __toString() - { - return (string) $this->getBody(); - } - - public function getContents($maxLength = -1) - { - return $this->getBody()->getContents(); - } - - public function close() - { - return $this->body ? $this->body->close() : true; - } - - public function detach() - { - $this->body = null; - $this->fields = $this->files = []; - - return $this; - } - - public function eof() - { - return $this->getBody()->eof(); - } - - public function tell() - { - return $this->body ? $this->body->tell() : 0; - } - - public function isSeekable() - { - return true; - } - - public function isReadable() - { - return true; - } - - public function isWritable() - { - return false; - } - - public function getSize() - { - return $this->getBody()->getSize(); - } - - public function seek($offset, $whence = SEEK_SET) - { - return $this->getBody()->seek($offset, $whence); - } - - public function read($length) - { - return $this->getBody()->read($length); - } - - public function write($string) - { - return false; - } - - /** - * Return a stream object that is built from the POST fields and files. - * - * If one has already been created, the previously created stream will be - * returned. - */ - private function getBody() - { - if ($this->body) { - return $this->body; - } elseif ($this->files || $this->forceMultipart) { - return $this->body = $this->createMultipart(); - } elseif ($this->fields) { - return $this->body = $this->createUrlEncoded(); - } else { - return $this->body = Stream\create(); - } - } - - /** - * Get the aggregator used to join multi-valued field parameters - * - * @return callable - */ - final protected function getAggregator() - { - if (!$this->aggregator) { - $this->aggregator = Query::phpAggregator(); - } - - return $this->aggregator; - } - - /** - * Creates a multipart/form-data body stream - * - * @return MultipartBody - */ - private function createMultipart() - { - // Flatten the nested query string values using the correct aggregator - $query = (string) (new Query($this->fields)) - ->setEncodingType(false) - ->setAggregator($this->getAggregator()); - // Convert the flattened query string back into an array - $fields = Query::fromString($query)->toArray(); - - return new MultipartBody($fields, $this->files); - } - - /** - * Creates an application/x-www-form-urlencoded stream body - * - * @return Stream\StreamInterface - */ - private function createUrlEncoded() - { - return Stream\create($this->getFields(true)); - } - - /** - * Get rid of any cached data - */ - private function mutate() - { - $this->body = null; - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Post/PostBodyInterface.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Post/PostBodyInterface.php deleted file mode 100644 index 4405ce21a42eaf99eb88d1134f464a9a44f9c07a..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Post/PostBodyInterface.php +++ /dev/null @@ -1,129 +0,0 @@ -headers = $headers; - $this->name = $name; - $this->prepareContent($content); - $this->prepareFilename($filename); - $this->prepareDefaultHeaders(); - } - - public function getName() - { - return $this->name; - } - - public function getFilename() - { - return $this->filename; - } - - public function getContent() - { - return $this->content; - } - - public function getHeaders() - { - return $this->headers; - } - - /** - * Prepares the contents of a POST file. - * - * @param mixed $content Content of the POST file - */ - private function prepareContent($content) - { - $this->content = $content; - - if (!($this->content instanceof StreamInterface)) { - $this->content = \GuzzleHttp\Stream\create($this->content); - } elseif ($this->content instanceof MultipartBody) { - if (!$this->hasHeader('Content-Disposition')) { - $disposition = 'form-data; name="' . $this->name .'"'; - $this->headers['Content-Disposition'] = $disposition; - } - - if (!$this->hasHeader('Content-Type')) { - $this->headers['Content-Type'] = sprintf( - "multipart/form-data; boundary=%s", - $this->content->getBoundary() - ); - } - } - } - - /** - * Applies a file name to the POST file based on various checks. - * - * @param string|null $filename Filename to apply (or null to guess) - */ - private function prepareFilename($filename) - { - $this->filename = $filename; - - if (!$this->filename && - $this->content instanceof MetadataStreamInterface - ) { - $this->filename = $this->content->getMetadata('uri'); - } - - if (!$this->filename || substr($this->filename, 0, 6) === 'php://') { - $this->filename = $this->name; - } - } - - /** - * Applies default Content-Disposition and Content-Type headers if needed. - */ - private function prepareDefaultHeaders() - { - // Set a default content-disposition header if one was no provided - if (!$this->hasHeader('Content-Disposition')) { - $this->headers['Content-Disposition'] = sprintf( - 'form-data; filename="%s"; name="%s"', - basename($this->filename), - $this->name - ); - } - - // Set a default Content-Type if one was not supplied - if (!$this->hasHeader('Content-Type')) { - $this->headers['Content-Type'] = Mimetypes::getInstance() - ->fromFilename($this->filename) ?: 'text/plain'; - } - } - - /** - * Check if a specific header exists on the POST file by name. - * - * @param string $name Case-insensitive header to check - * - * @return bool - */ - private function hasHeader($name) - { - return isset(array_change_key_case($this->headers)[strtolower($name)]); - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Post/PostFileInterface.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Post/PostFileInterface.php deleted file mode 100644 index 205dd9676c9bc7e4395955d276336578101cc082..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Post/PostFileInterface.php +++ /dev/null @@ -1,42 +0,0 @@ -add($key, $value); - $foundDuplicates = true; - } elseif ($paramIsPhpStyleArray) { - $q[$key] = array($value); - } else { - $q[$key] = $value; - } - } else { - $q->add($key, null); - } - } - - // Use the duplicate aggregator if duplicates were found and not using - // PHP style arrays. - if ($foundDuplicates && !$foundPhpStyle) { - $q->setAggregator(self::duplicateAggregator()); - } - - return $q; - } - - /** - * Convert the query string parameters to a query string string - * - * @return string - */ - public function __toString() - { - if (!$this->data) { - return ''; - } - - // The default aggregator is statically cached - static $defaultAggregator; - - if (!$this->aggregator) { - if (!$defaultAggregator) { - $defaultAggregator = self::phpAggregator(); - } - $this->aggregator = $defaultAggregator; - } - - $result = ''; - $aggregator = $this->aggregator; - - foreach ($aggregator($this->data) as $key => $values) { - foreach ($values as $value) { - if ($result) { - $result .= '&'; - } - if ($this->encoding == self::RFC1738) { - $result .= urlencode($key); - if ($value !== null) { - $result .= '=' . urlencode($value); - } - } elseif ($this->encoding == self::RFC3986) { - $result .= rawurlencode($key); - if ($value !== null) { - $result .= '=' . rawurlencode($value); - } - } else { - $result .= $key; - if ($value !== null) { - $result .= '=' . $value; - } - } - } - } - - return $result; - } - - /** - * Controls how multi-valued query string parameters are aggregated into a - * string. - * - * $query->setAggregator($query::duplicateAggregator()); - * - * @param callable $aggregator Callable used to convert a deeply nested - * array of query string variables into a flattened array of key value - * pairs. The callable accepts an array of query data and returns a - * flattened array of key value pairs where each value is an array of - * strings. - * - * @return self - */ - public function setAggregator(callable $aggregator) - { - $this->aggregator = $aggregator; - - return $this; - } - - /** - * Specify how values are URL encoded - * - * @param string|bool $type One of 'RFC1738', 'RFC3986', or false to disable encoding - * - * @return self - * @throws \InvalidArgumentException - */ - public function setEncodingType($type) - { - if ($type === false || $type === self::RFC1738 || $type === self::RFC3986) { - $this->encoding = $type; - } else { - throw new \InvalidArgumentException('Invalid URL encoding type'); - } - - return $this; - } - - /** - * Query string aggregator that does not aggregate nested query string - * values and allows duplicates in the resulting array. - * - * Example: http://test.com?q=1&q=2 - * - * @return callable - */ - public static function duplicateAggregator() - { - return function (array $data) { - return self::walkQuery($data, '', function ($key, $prefix) { - return is_int($key) ? $prefix : "{$prefix}[{$key}]"; - }); - }; - } - - /** - * Aggregates nested query string variables using the same technique as - * ``http_build_query()``. - * - * @param bool $numericIndices Pass false to not include numeric indices - * when multi-values query string parameters are present. - * - * @return callable - */ - public static function phpAggregator($numericIndices = true) - { - return function (array $data) use ($numericIndices) { - return self::walkQuery( - $data, - '', - function ($key, $prefix) use ($numericIndices) { - return !$numericIndices && is_int($key) - ? "{$prefix}[]" - : "{$prefix}[{$key}]"; - } - ); - }; - } - - /** - * Easily create query aggregation functions by providing a key prefix - * function to this query string array walker. - * - * @param array $query Query string to walk - * @param string $keyPrefix Key prefix (start with '') - * @param callable $prefixer Function used to create a key prefix - * - * @return array - */ - public static function walkQuery(array $query, $keyPrefix, callable $prefixer) - { - $result = []; - foreach ($query as $key => $value) { - if ($keyPrefix) { - $key = $prefixer($key, $keyPrefix); - } - if (is_array($value)) { - $result += self::walkQuery($value, $key, $prefixer); - } elseif (isset($result[$key])) { - $result[$key][] = $value; - } else { - $result[$key] = array($value); - } - } - - return $result; - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Subscriber/Cookie.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Subscriber/Cookie.php deleted file mode 100644 index 4b8a2c081be3745c79afc9a095a9f50cc6cb6f58..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Subscriber/Cookie.php +++ /dev/null @@ -1,59 +0,0 @@ -cookieJar = $cookieJar ?: new CookieJar(); - } - - public function getEvents() - { - // Fire the cookie plugin complete event before redirecting - return [ - 'before' => ['onBefore'], - 'complete' => ['onComplete', RequestEvents::REDIRECT_RESPONSE + 10] - ]; - } - - /** - * Get the cookie cookieJar - * - * @return CookieJarInterface - */ - public function getCookieJar() - { - return $this->cookieJar; - } - - public function onBefore(BeforeEvent $event) - { - $this->cookieJar->addCookieHeader($event->getRequest()); - } - - public function onComplete(CompleteEvent $event) - { - $this->cookieJar->extractCookies( - $event->getRequest(), - $event->getResponse() - ); - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Subscriber/History.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Subscriber/History.php deleted file mode 100644 index b2a49e04453684b9772b4c5536b3735847044802..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Subscriber/History.php +++ /dev/null @@ -1,138 +0,0 @@ -limit = $limit; - } - - public function getEvents() - { - return [ - 'complete' => ['onComplete', RequestEvents::EARLY], - 'error' => ['onError', RequestEvents::EARLY], - ]; - } - - /** - * Convert to a string that contains all request and response headers - * - * @return string - */ - public function __toString() - { - $lines = array(); - foreach ($this->transactions as $entry) { - $response = isset($entry['response']) ? $entry['response'] : ''; - $lines[] = '> ' . trim($entry['request']) . "\n\n< " . trim($response) . "\n"; - } - - return implode("\n", $lines); - } - - public function onComplete(CompleteEvent $event) - { - $this->add($event->getRequest(), $event->getResponse()); - } - - public function onError(ErrorEvent $event) - { - $this->add($event->getRequest(), $event->getResponse()); - } - - /** - * Returns an Iterator that yields associative array values where each - * associative array contains a 'request' and 'response' key. - * - * @return \Iterator - */ - public function getIterator() - { - return new \ArrayIterator($this->transactions); - } - - /** - * Get all of the requests sent through the plugin - * - * @return RequestInterface[] - */ - public function getRequests() - { - return array_map(function ($t) { - return $t['request']; - }, $this->transactions); - } - - /** - * Get the number of requests in the history - * - * @return int - */ - public function count() - { - return count($this->transactions); - } - - /** - * Get the last request sent - * - * @return RequestInterface - */ - public function getLastRequest() - { - return end($this->transactions)['request']; - } - - /** - * Get the last response in the history - * - * @return ResponseInterface|null - */ - public function getLastResponse() - { - return end($this->transactions)['response']; - } - - /** - * Clears the history - */ - public function clear() - { - $this->transactions = array(); - } - - /** - * Add a request to the history - * - * @param RequestInterface $request Request to add - * @param ResponseInterface $response Response of the request - */ - private function add( - RequestInterface $request, - ResponseInterface $response = null - ) { - $this->transactions[] = ['request' => $request, 'response' => $response]; - if (count($this->transactions) > $this->limit) { - array_shift($this->transactions); - } - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Subscriber/HttpError.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Subscriber/HttpError.php deleted file mode 100644 index f2f72f15e9d1337950f307bc023c60a870b169e3..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Subscriber/HttpError.php +++ /dev/null @@ -1,34 +0,0 @@ - ['onComplete', RequestEvents::VERIFY_RESPONSE]]; - } - - /** - * Throw a RequestException on an HTTP protocol error - * - * @param CompleteEvent $event Emitted event - * @throws RequestException - */ - public function onComplete(CompleteEvent $event) - { - $code = (string) $event->getResponse()->getStatusCode(); - // Throw an exception for an unsuccessful response - if ($code[0] === '4' || $code[0] === '5') { - throw RequestException::create($event->getRequest(), $event->getResponse()); - } - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Subscriber/Mock.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Subscriber/Mock.php deleted file mode 100644 index 99a3d18d72cd77f8d059f75ce7126f0063d433e3..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Subscriber/Mock.php +++ /dev/null @@ -1,143 +0,0 @@ -factory = new MessageFactory(); - $this->readBodies = $readBodies; - $this->addMultiple($items); - } - - public function getEvents() - { - // Fire the event last, after signing - return ['before' => ['onBefore', RequestEvents::SIGN_REQUEST - 10]]; - } - - /** - * @throws \OutOfBoundsException|\Exception - */ - public function onBefore(BeforeEvent $event) - { - if (!$item = array_shift($this->queue)) { - throw new \OutOfBoundsException('Mock queue is empty'); - } elseif ($item instanceof RequestException) { - throw $item; - } - - // Emulate the receiving of the response headers - $request = $event->getRequest(); - $transaction = new Transaction($event->getClient(), $request); - $transaction->setResponse($item); - $request->getEmitter()->emit( - 'headers', - new HeadersEvent($transaction) - ); - - // Emulate reading a response body - if ($this->readBodies && $request->getBody()) { - while (!$request->getBody()->eof()) { - $request->getBody()->read(8096); - } - } - - $event->intercept($item); - } - - public function count() - { - return count($this->queue); - } - - /** - * Add a response to the end of the queue - * - * @param string|ResponseInterface $response Response or path to response file - * - * @return self - * @throws \InvalidArgumentException if a string or Response is not passed - */ - public function addResponse($response) - { - if (is_string($response)) { - $response = file_exists($response) - ? $this->factory->fromMessage(file_get_contents($response)) - : $this->factory->fromMessage($response); - } elseif (!($response instanceof ResponseInterface)) { - throw new \InvalidArgumentException('Response must a message ' - . 'string, response object, or path to a file'); - } - - $this->queue[] = $response; - - return $this; - } - - /** - * Add an exception to the end of the queue - * - * @param RequestException $e Exception to throw when the request is executed - * - * @return self - */ - public function addException(RequestException $e) - { - $this->queue[] = $e; - - return $this; - } - - /** - * Add multiple items to the queue - * - * @param array $items Items to add - */ - public function addMultiple(array $items) - { - foreach ($items as $item) { - if ($item instanceof RequestException) { - $this->addException($item); - } else { - $this->addResponse($item); - } - } - } - - /** - * Clear the queue - */ - public function clearQueue() - { - $this->queue = []; - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Subscriber/Prepare.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Subscriber/Prepare.php deleted file mode 100644 index 2d82acd6d8a443844b4e67ff41f4af6f2461d9a2..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Subscriber/Prepare.php +++ /dev/null @@ -1,136 +0,0 @@ - ['onBefore', RequestEvents::PREPARE_REQUEST]]; - } - - public function onBefore(BeforeEvent $event) - { - $request = $event->getRequest(); - - // Set the appropriate Content-Type for a request if one is not set and - // there are form fields - if (!($body = $request->getBody())) { - return; - } - - $this->addContentLength($request, $body); - - if ($body instanceof PostBodyInterface) { - // Synchronize the POST body with the request's headers - $body->applyRequestHeaders($request); - } elseif (!$request->hasHeader('Content-Type')) { - $this->addContentType($request, $body); - } - - $this->addExpectHeader($request, $body); - } - - private function addContentType( - RequestInterface $request, - StreamInterface $body - ) { - if (!($body instanceof MetadataStreamInterface)) { - return; - } - - if (!($uri = $body->getMetadata('uri'))) { - return; - } - - // Guess the content-type based on the stream's "uri" metadata value. - // The file extension is used to determine the appropriate mime-type. - if ($contentType = Mimetypes::getInstance()->fromFilename($uri)) { - $request->setHeader('Content-Type', $contentType); - } - } - - private function addContentLength( - RequestInterface $request, - StreamInterface $body - ) { - // Set the Content-Length header if it can be determined, and never - // send a Transfer-Encoding: chunked and Content-Length header in - // the same request. - if ($request->hasHeader('Content-Length')) { - // Remove transfer-encoding if content-length is set. - $request->removeHeader('Transfer-Encoding'); - return; - } - - if ($request->hasHeader('Transfer-Encoding')) { - return; - } - - if (null !== ($size = $body->getSize())) { - $request->setHeader('Content-Length', $size) - ->removeHeader('Transfer-Encoding'); - } elseif ('1.1' == $request->getProtocolVersion()) { - // Use chunked Transfer-Encoding if there is no determinable - // content-length header and we're using HTTP/1.1. - $request->setHeader('Transfer-Encoding', 'chunked') - ->removeHeader('Content-Length'); - } - } - - private function addExpectHeader( - RequestInterface $request, - StreamInterface $body - ) { - // Determine if the Expect header should be used - if ($request->hasHeader('Expect')) { - return; - } - - $expect = $request->getConfig()['expect']; - - // Return if disabled or if you're not using HTTP/1.1 - if ($expect === false || $request->getProtocolVersion() !== '1.1') { - return; - } - - // The expect header is unconditionally enabled - if ($expect === true) { - $request->setHeader('Expect', '100-Continue'); - return; - } - - // By default, send the expect header when the payload is > 1mb - if ($expect === null) { - $expect = 1048576; - } - - // Always add if the body cannot be rewound, the size cannot be - // determined, or the size is greater than the cutoff threshold - $size = $body->getSize(); - if ($size === null || $size >= (int) $expect || !$body->isSeekable()) { - $request->setHeader('Expect', '100-Continue'); - } - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Subscriber/Redirect.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Subscriber/Redirect.php deleted file mode 100644 index bd8988d8df013cc610068e9dd9b9c5981c52a87e..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Subscriber/Redirect.php +++ /dev/null @@ -1,172 +0,0 @@ - ['onComplete', RequestEvents::REDIRECT_RESPONSE]]; - } - - /** - * Rewind the entity body of the request if needed - * - * @param RequestInterface $redirectRequest - * @throws CouldNotRewindStreamException - */ - public static function rewindEntityBody(RequestInterface $redirectRequest) - { - // Rewind the entity body of the request if needed - if ($redirectRequest->getBody()) { - $body = $redirectRequest->getBody(); - // Only rewind the body if some of it has been read already, and - // throw an exception if the rewind fails - if ($body->tell() && !$body->seek(0)) { - throw new CouldNotRewindStreamException( - 'Unable to rewind the non-seekable request body after redirecting', - $redirectRequest - ); - } - } - } - - /** - * Called when a request receives a redirect response - * - * @param CompleteEvent $event Event emitted - * @throws TooManyRedirectsException - */ - public function onComplete(CompleteEvent $event) - { - $response = $event->getResponse(); - - if (substr($response->getStatusCode(), 0, 1) != '3' || - !$response->hasHeader('Location') - ) { - return; - } - - $redirectCount = 0; - $request = $event->getRequest(); - $redirectResponse = $response; - $max = $request->getConfig()->getPath('redirect/max') ?: 5; - - do { - if (++$redirectCount > $max) { - throw new TooManyRedirectsException( - "Will not follow more than {$redirectCount} redirects", - $request - ); - } - $redirectRequest = $this->createRedirectRequest($request, $redirectResponse); - $redirectResponse = $event->getClient()->send($redirectRequest); - } while (substr($redirectResponse->getStatusCode(), 0, 1) == '3' && - $redirectResponse->hasHeader('Location') - ); - - if ($redirectResponse !== $response) { - $event->intercept($redirectResponse); - } - } - - /** - * Create a redirect request for a specific request object - * - * Takes into account strict RFC compliant redirection (e.g. redirect POST - * with POST) vs doing what most clients do (e.g. redirect POST with GET). - * - * @param RequestInterface $request - * @param ResponseInterface $response - * - * @return RequestInterface Returns a new redirect request - * @throws CouldNotRewindStreamException If the body cannot be rewound. - */ - private function createRedirectRequest( - RequestInterface $request, - ResponseInterface $response - ) { - $config = $request->getConfig(); - - // Use a GET request if this is an entity enclosing request and we are - // not forcing RFC compliance, but rather emulating what all browsers - // would do. Be sure to disable redirects on the clone. - $redirectRequest = clone $request; - $redirectRequest->getEmitter()->detach($this); - $statusCode = $response->getStatusCode(); - - if ($statusCode == 303 || - ($statusCode <= 302 && $request->getBody() && - !$config->getPath('redirect/strict')) - ) { - $redirectRequest->setMethod('GET'); - $redirectRequest->setBody(null); - } - - $this->setRedirectUrl($redirectRequest, $response); - $this->rewindEntityBody($redirectRequest); - - // Add the Referer header if it is told to do so and only - // add the header if we are not redirecting from https to http. - if ($config->getPath('redirect/referer') && ( - $redirectRequest->getScheme() == 'https' || - $redirectRequest->getScheme() == $request->getScheme() - )) { - $url = Url::fromString($request->getUrl()); - $url->setUsername(null)->setPassword(null); - $redirectRequest->setHeader('Referer', (string) $url); - } - - return $redirectRequest; - } - - /** - * Set the appropriate URL on the request based on the location header - * - * @param RequestInterface $redirectRequest - * @param ResponseInterface $response - */ - private function setRedirectUrl( - RequestInterface $redirectRequest, - ResponseInterface $response - ) { - $location = $response->getHeader('Location'); - $location = Url::fromString($location); - - // Combine location with the original URL if it is not absolute. - if (!$location->isAbsolute()) { - $originalUrl = Url::fromString($redirectRequest->getUrl()); - // Remove query string parameters and just take what is present on - // the redirect Location header - $originalUrl->getQuery()->clear(); - $location = $originalUrl->combine($location); - } - - $redirectRequest->setUrl($location); - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/ToArrayInterface.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/ToArrayInterface.php deleted file mode 100644 index 7c4120fbca6c89d19e0c8cf4b5f5ba08b67caf88..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/ToArrayInterface.php +++ /dev/null @@ -1,16 +0,0 @@ - array('prefix' => '', 'joiner' => ',', 'query' => false), - '+' => array('prefix' => '', 'joiner' => ',', 'query' => false), - '#' => array('prefix' => '#', 'joiner' => ',', 'query' => false), - '.' => array('prefix' => '.', 'joiner' => '.', 'query' => false), - '/' => array('prefix' => '/', 'joiner' => '/', 'query' => false), - ';' => array('prefix' => ';', 'joiner' => ';', 'query' => true), - '?' => array('prefix' => '?', 'joiner' => '&', 'query' => true), - '&' => array('prefix' => '&', 'joiner' => '&', 'query' => true) - ); - - /** @var array Delimiters */ - private static $delims = array(':', '/', '?', '#', '[', ']', '@', '!', '$', - '&', '\'', '(', ')', '*', '+', ',', ';', '='); - - /** @var array Percent encoded delimiters */ - private static $delimsPct = array('%3A', '%2F', '%3F', '%23', '%5B', '%5D', - '%40', '%21', '%24', '%26', '%27', '%28', '%29', '%2A', '%2B', '%2C', - '%3B', '%3D'); - - public function expand($template, array $variables) - { - if (false === strpos($template, '{')) { - return $template; - } - - $this->template = $template; - $this->variables = $variables; - - return preg_replace_callback( - '/\{([^\}]+)\}/', - [$this, 'expandMatch'], - $this->template - ); - } - - /** - * Parse an expression into parts - * - * @param string $expression Expression to parse - * - * @return array Returns an associative array of parts - */ - private function parseExpression($expression) - { - $result = array(); - - if (isset(self::$operatorHash[$expression[0]])) { - $result['operator'] = $expression[0]; - $expression = substr($expression, 1); - } else { - $result['operator'] = ''; - } - - foreach (explode(',', $expression) as $value) { - $value = trim($value); - $varspec = array(); - if ($colonPos = strpos($value, ':')) { - $varspec['value'] = substr($value, 0, $colonPos); - $varspec['modifier'] = ':'; - $varspec['position'] = (int) substr($value, $colonPos + 1); - } elseif (substr($value, -1) == '*') { - $varspec['modifier'] = '*'; - $varspec['value'] = substr($value, 0, -1); - } else { - $varspec['value'] = (string) $value; - $varspec['modifier'] = ''; - } - $result['values'][] = $varspec; - } - - return $result; - } - - /** - * Process an expansion - * - * @param array $matches Matches met in the preg_replace_callback - * - * @return string Returns the replacement string - */ - private function expandMatch(array $matches) - { - static $rfc1738to3986 = array('+' => '%20', '%7e' => '~'); - - $replacements = array(); - $parsed = self::parseExpression($matches[1]); - $prefix = self::$operatorHash[$parsed['operator']]['prefix']; - $joiner = self::$operatorHash[$parsed['operator']]['joiner']; - $useQuery = self::$operatorHash[$parsed['operator']]['query']; - - foreach ($parsed['values'] as $value) { - - if (!isset($this->variables[$value['value']])) { - continue; - } - - $variable = $this->variables[$value['value']]; - $actuallyUseQuery = $useQuery; - $expanded = ''; - - if (is_array($variable)) { - - $isAssoc = $this->isAssoc($variable); - $kvp = array(); - foreach ($variable as $key => $var) { - - if ($isAssoc) { - $key = rawurlencode($key); - $isNestedArray = is_array($var); - } else { - $isNestedArray = false; - } - - if (!$isNestedArray) { - $var = rawurlencode($var); - if ($parsed['operator'] == '+' || - $parsed['operator'] == '#' - ) { - $var = $this->decodeReserved($var); - } - } - - if ($value['modifier'] == '*') { - if ($isAssoc) { - if ($isNestedArray) { - // Nested arrays must allow for deeply nested - // structures. - $var = strtr( - http_build_query([$key => $var]), - $rfc1738to3986 - ); - } else { - $var = $key . '=' . $var; - } - } elseif ($key > 0 && $actuallyUseQuery) { - $var = $value['value'] . '=' . $var; - } - } - - $kvp[$key] = $var; - } - - if (empty($variable)) { - $actuallyUseQuery = false; - } elseif ($value['modifier'] == '*') { - $expanded = implode($joiner, $kvp); - if ($isAssoc) { - // Don't prepend the value name when using the explode - // modifier with an associative array. - $actuallyUseQuery = false; - } - } else { - if ($isAssoc) { - // When an associative array is encountered and the - // explode modifier is not set, then the result must be - // a comma separated list of keys followed by their - // respective values. - foreach ($kvp as $k => &$v) { - $v = $k . ',' . $v; - } - } - $expanded = implode(',', $kvp); - } - - } else { - if ($value['modifier'] == ':') { - $variable = substr($variable, 0, $value['position']); - } - $expanded = rawurlencode($variable); - if ($parsed['operator'] == '+' || $parsed['operator'] == '#') { - $expanded = $this->decodeReserved($expanded); - } - } - - if ($actuallyUseQuery) { - if (!$expanded && $joiner != '&') { - $expanded = $value['value']; - } else { - $expanded = $value['value'] . '=' . $expanded; - } - } - - $replacements[] = $expanded; - } - - $ret = implode($joiner, $replacements); - if ($ret && $prefix) { - return $prefix . $ret; - } - - return $ret; - } - - /** - * Determines if an array is associative. - * - * This makes the assumption that input arrays are sequences or hashes. - * This assumption is a tradeoff for accuracy in favor of speed, but it - * should work in almost every case where input is supplied for a URI - * template. - * - * @param array $array Array to check - * - * @return bool - */ - private function isAssoc(array $array) - { - return $array && array_keys($array)[0] !== 0; - } - - /** - * Removes percent encoding on reserved characters (used with + and # - * modifiers). - * - * @param string $string String to fix - * - * @return string - */ - private function decodeReserved($string) - { - return str_replace(self::$delimsPct, self::$delims, $string); - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Url.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Url.php deleted file mode 100644 index a305a768c5bf87ee1118ee045775be1d8f7156ac..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/Url.php +++ /dev/null @@ -1,585 +0,0 @@ - 80, 'https' => 443, 'ftp' => 21]; - - /** @var Query Query part of the URL */ - private $query; - - /** - * Factory method to create a new URL from a URL string - * - * @param string $url Full URL used to create a Url object - * - * @return Url - * @throws \InvalidArgumentException - */ - public static function fromString($url) - { - static $defaults = array('scheme' => null, 'host' => null, - 'path' => null, 'port' => null, 'query' => null, - 'user' => null, 'pass' => null, 'fragment' => null); - - if (false === ($parts = parse_url($url))) { - throw new \InvalidArgumentException('Unable to parse malformed ' - . 'url: ' . $url); - } - - $parts += $defaults; - - // Convert the query string into a Query object - if ($parts['query'] || 0 !== strlen($parts['query'])) { - $parts['query'] = Query::fromString($parts['query']); - } - - return new static($parts['scheme'], $parts['host'], $parts['user'], - $parts['pass'], $parts['port'], $parts['path'], $parts['query'], - $parts['fragment']); - } - - /** - * Build a URL from parse_url parts. The generated URL will be a relative - * URL if a scheme or host are not provided. - * - * @param array $parts Array of parse_url parts - * - * @return string - */ - public static function buildUrl(array $parts) - { - $url = $scheme = ''; - - if (!empty($parts['scheme'])) { - $scheme = $parts['scheme']; - $url .= $scheme . ':'; - } - - if (!empty($parts['host'])) { - $url .= '//'; - if (isset($parts['user'])) { - $url .= $parts['user']; - if (isset($parts['pass'])) { - $url .= ':' . $parts['pass']; - } - $url .= '@'; - } - - $url .= $parts['host']; - - // Only include the port if it is not the default port of the scheme - if (isset($parts['port']) && - (!isset(self::$defaultPorts[$scheme]) || - $parts['port'] != self::$defaultPorts[$scheme]) - ) { - $url .= ':' . $parts['port']; - } - } - - // Add the path component if present - if (isset($parts['path']) && strlen($parts['path'])) { - // Always ensure that the path begins with '/' if set and something - // is before the path - if (isset($parts['host']) && $parts['path'][0] != '/') { - $url .= '/'; - } - $url .= $parts['path']; - } - - // Add the query string if present - if (isset($parts['query'])) { - $queryStr = (string) $parts['query']; - if ($queryStr || $queryStr === '0') { - $url .= '?' . $queryStr; - } - } - - // Ensure that # is only added to the url if fragment contains anything. - if (isset($parts['fragment'])) { - $url .= '#' . $parts['fragment']; - } - - return $url; - } - - /** - * Create a new URL from URL parts - * - * @param string $scheme Scheme of the URL - * @param string $host Host of the URL - * @param string $username Username of the URL - * @param string $password Password of the URL - * @param int $port Port of the URL - * @param string $path Path of the URL - * @param Query|array|string $query Query string of the URL - * @param string $fragment Fragment of the URL - */ - public function __construct( - $scheme, - $host, - $username = null, - $password = null, - $port = null, - $path = null, - Query $query = null, - $fragment = null - ) { - $this->scheme = $scheme; - $this->host = $host; - $this->port = $port; - $this->username = $username; - $this->password = $password; - $this->fragment = $fragment; - if (!$query) { - $this->query = new Query(); - } else { - $this->setQuery($query); - } - $this->setPath($path); - } - - /** - * Clone the URL - */ - public function __clone() - { - $this->query = clone $this->query; - } - - /** - * Returns the URL as a URL string - * - * @return string - */ - public function __toString() - { - return static::buildUrl($this->getParts()); - } - - /** - * Get the parts of the URL as an array - * - * @return array - */ - public function getParts() - { - return array( - 'scheme' => $this->scheme, - 'user' => $this->username, - 'pass' => $this->password, - 'host' => $this->host, - 'port' => $this->port, - 'path' => $this->path, - 'query' => $this->query, - 'fragment' => $this->fragment, - ); - } - - /** - * Set the host of the request. - * - * @param string $host Host to set (e.g. www.yahoo.com, yahoo.com) - * - * @return Url - */ - public function setHost($host) - { - if (strpos($host, ':') === false) { - $this->host = $host; - } else { - list($host, $port) = explode(':', $host); - $this->host = $host; - $this->setPort($port); - } - - return $this; - } - - /** - * Get the host part of the URL - * - * @return string - */ - public function getHost() - { - return $this->host; - } - - /** - * Set the scheme part of the URL (http, https, ftp, etc.) - * - * @param string $scheme Scheme to set - * - * @return Url - */ - public function setScheme($scheme) - { - // Remove the default port if one is specified - if ($this->port && isset(self::$defaultPorts[$this->scheme]) && - self::$defaultPorts[$this->scheme] == $this->port - ) { - $this->port = null; - } - - $this->scheme = $scheme; - - return $this; - } - - /** - * Get the scheme part of the URL - * - * @return string - */ - public function getScheme() - { - return $this->scheme; - } - - /** - * Set the port part of the URL - * - * @param int $port Port to set - * - * @return Url - */ - public function setPort($port) - { - $this->port = $port; - - return $this; - } - - /** - * Get the port part of the URl. - * - * If no port was set, this method will return the default port for the - * scheme of the URI. - * - * @return int|null - */ - public function getPort() - { - if ($this->port) { - return $this->port; - } elseif (isset(self::$defaultPorts[$this->scheme])) { - return self::$defaultPorts[$this->scheme]; - } - - return null; - } - - /** - * Set the path part of the URL - * - * @param string $path Path string to set - * - * @return Url - */ - public function setPath($path) - { - static $search = [' ', '?']; - static $replace = ['%20', '%3F']; - $this->path = str_replace($search, $replace, $path); - - return $this; - } - - /** - * Removes dot segments from a URL - * - * @return Url - * @link http://tools.ietf.org/html/rfc3986#section-5.2.4 - */ - public function removeDotSegments() - { - static $noopPaths = ['' => true, '/' => true, '*' => true]; - static $ignoreSegments = ['' => true, '.' => true, '..' => true]; - - if (isset($noopPaths[$this->path])) { - return $this; - } - - $results = []; - $segments = $this->getPathSegments(); - foreach ($segments as $segment) { - if ($segment == '..') { - array_pop($results); - } elseif (!isset($ignoreSegments[$segment])) { - $results[] = $segment; - } - } - - // Combine the normalized parts and add the leading slash if needed - if ($this->path[0] == '/') { - $this->path = '/' . implode('/', $results); - } else { - $this->path = implode('/', $results); - } - - // Add the trailing slash if necessary - if ($this->path != '/' && isset($ignoreSegments[end($segments)])) { - $this->path .= '/'; - } - - return $this; - } - - /** - * Add a relative path to the currently set path. - * - * @param string $relativePath Relative path to add - * - * @return Url - */ - public function addPath($relativePath) - { - if ($relativePath != '/' && - is_string($relativePath) && - strlen($relativePath) > 0 - ) { - // Add a leading slash if needed - if ($relativePath[0] != '/') { - $relativePath = '/' . $relativePath; - } - $this->setPath(str_replace('//', '/', $this->path . $relativePath)); - } - - return $this; - } - - /** - * Get the path part of the URL - * - * @return string - */ - public function getPath() - { - return $this->path; - } - - /** - * Get the path segments of the URL as an array - * - * @return array - */ - public function getPathSegments() - { - return explode('/', $this->path); - } - - /** - * Set the password part of the URL - * - * @param string $password Password to set - * - * @return Url - */ - public function setPassword($password) - { - $this->password = $password; - - return $this; - } - - /** - * Get the password part of the URL - * - * @return null|string - */ - public function getPassword() - { - return $this->password; - } - - /** - * Set the username part of the URL - * - * @param string $username Username to set - * - * @return Url - */ - public function setUsername($username) - { - $this->username = $username; - - return $this; - } - - /** - * Get the username part of the URl - * - * @return null|string - */ - public function getUsername() - { - return $this->username; - } - - /** - * Get the query part of the URL as a Query object - * - * @return Query - */ - public function getQuery() - { - return $this->query; - } - - /** - * Set the query part of the URL - * - * @param Query|string|array $query Query string value to set. Can - * be a string that will be parsed into a Query object, an array - * of key value pairs, or a Query object. - * - * @return Url - * @throws \InvalidArgumentException - */ - public function setQuery($query) - { - if ($query instanceof Query) { - $this->query = $query; - } elseif (is_string($query)) { - $this->query = Query::fromString($query); - } elseif (is_array($query)) { - $this->query = new Query($query); - } else { - throw new \InvalidArgumentException('Query must be a ' - . 'QueryInterface, array, or string'); - } - - return $this; - } - - /** - * Get the fragment part of the URL - * - * @return null|string - */ - public function getFragment() - { - return $this->fragment; - } - - /** - * Set the fragment part of the URL - * - * @param string $fragment Fragment to set - * - * @return Url - */ - public function setFragment($fragment) - { - $this->fragment = $fragment; - - return $this; - } - - /** - * Check if this is an absolute URL - * - * @return bool - */ - public function isAbsolute() - { - return $this->scheme && $this->host; - } - - /** - * Combine the URL with another URL and return a new URL instance. - * - * Follows the rules specific in RFC 3986 section 5.4. - * - * @param string $url Relative URL to combine with - * - * @return Url - * @throws \InvalidArgumentException - * @link http://tools.ietf.org/html/rfc3986#section-5.4 - */ - public function combine($url) - { - $url = static::fromString($url); - - // Use the more absolute URL as the base URL - if (!$this->isAbsolute() && $url->isAbsolute()) { - $url = $url->combine($this); - } - - $parts = $url->getParts(); - - // Passing a URL with a scheme overrides everything - if ($parts['scheme']) { - return new static( - $parts['scheme'], - $parts['host'], - $parts['user'], - $parts['pass'], - $parts['port'], - $parts['path'], - clone $parts['query'], - $parts['fragment'] - ); - } - - // Setting a host overrides the entire rest of the URL - if ($parts['host']) { - return new static( - $this->scheme, - $parts['host'], - $parts['user'], - $parts['pass'], - $parts['port'], - $parts['path'], - clone $parts['query'], - $parts['fragment'] - ); - } - - if (!$parts['path']) { - // The relative URL has no path, so check if it is just a query - $path = $this->path ?: ''; - $query = count($parts['query']) ? $parts['query'] : $this->query; - } else { - $query = $parts['query']; - if ($parts['path'][0] == '/' || !$this->path) { - // Overwrite the existing path if the rel path starts with "/" - $path = $parts['path']; - } else { - // If the relative URL does not have a path or the base URL - // path does not end in a "/" then overwrite the existing path - // up to the last "/" - $path = substr($this->path, 0, strrpos($this->path, '/') + 1) . $parts['path']; - } - } - - $result = new self( - $this->scheme, - $this->host, - $this->username, - $this->password, - $this->port, - $path, - clone $query, - $parts['fragment'] - ); - - if ($path) { - $result->removeDotSegments(); - } - - return $result; - } -} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/cacert.pem b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/cacert.pem deleted file mode 100644 index 9794dfb70f44b03eca060bb4f72462ac0bbb9a94..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/cacert.pem +++ /dev/null @@ -1,3866 +0,0 @@ -## -## ca-bundle.crt -- Bundle of CA Root Certificates -## -## Certificate data from Mozilla as of: Tue Apr 22 08:29:31 2014 -## -## 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://mxr.mozilla.org/mozilla-release/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1 -## -## 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. -## - - -GTE CyberTrust Global Root -========================== ------BEGIN CERTIFICATE----- -MIICWjCCAcMCAgGlMA0GCSqGSIb3DQEBBAUAMHUxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9HVEUg -Q29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNvbHV0aW9ucywgSW5jLjEjMCEG -A1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJvb3QwHhcNOTgwODEzMDAyOTAwWhcNMTgwODEz -MjM1OTAwWjB1MQswCQYDVQQGEwJVUzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQL -Ex5HVEUgQ3liZXJUcnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0 -IEdsb2JhbCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVD6C28FCc6HrHiM3dFw4u -sJTQGz0O9pTAipTHBsiQl8i4ZBp6fmw8U+E3KHNgf7KXUwefU/ltWJTSr41tiGeA5u2ylc9yMcql -HHK6XALnZELn+aks1joNrI1CqiQBOeacPwGFVw1Yh0X404Wqk2kmhXBIgD8SFcd5tB8FLztimQID -AQABMA0GCSqGSIb3DQEBBAUAA4GBAG3rGwnpXtlR22ciYaQqPEh346B8pt5zohQDhT37qw4wxYMW -M4ETCJ57NE7fQMh017l93PR2VX2bY1QY6fDq81yx2YtCHrnAlU66+tXifPVoYb+O7AWXX1uw16OF -NMQkpw0PlZPvy5TYnh+dXIVtx6quTx8itc2VrbqnzPmrC3p/ ------END CERTIFICATE----- - -Thawte Server CA -================ ------BEGIN CERTIFICATE----- -MIIDEzCCAnygAwIBAgIBATANBgkqhkiG9w0BAQQFADCBxDELMAkGA1UEBhMCWkExFTATBgNVBAgT -DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3Vs -dGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UE -AxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5j -b20wHhcNOTYwODAxMDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBxDELMAkGA1UEBhMCWkExFTATBgNV -BAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29u -c3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcG -A1UEAxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0 -ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANOkUG7I/1Zr5s9dtuoMaHVHoqrC2oQl -/Kj0R1HahbUgdJSGHg91yekIYfUGbTBuFRkC6VLAYttNmZ7iagxEOM3+vuNkCXDF/rFrKbYvScg7 -1CcEJRCXL+eQbcAoQpnXTEPew/UhbVSfXcNY4cDk2VuwuNy0e982OsK1ZiIS1ocNAgMBAAGjEzAR -MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAB/pMaVz7lcxG7oWDTSEwjsrZqG9J -GubaUeNgcGyEYRGhGshIPllDfU+VPaGLtwtimHp1it2ITk6eQNuozDJ0uW8NxuOzRAvZim+aKZuZ -GCg70eNAKJpaPNW15yAbi8qkq43pUdniTCxZqdq5snUb9kLy78fyGPmJvKP/iiMucEc= ------END CERTIFICATE----- - -Thawte Premium Server CA -======================== ------BEGIN CERTIFICATE----- -MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkExFTATBgNVBAgT -DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3Vs -dGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UE -AxMYVGhhd3RlIFByZW1pdW0gU2VydmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZl -ckB0aGF3dGUuY29tMB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYT -AlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsGA1UEChMU -VGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2 -aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNlcnZlciBDQTEoMCYGCSqGSIb3DQEJARYZ -cHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2 -aovXwlue2oFBYo847kkEVdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIh -Udib0GfQug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMRuHM/ -qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQAm -SCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUIhfzJATj/Tb7yFkJD57taRvvBxhEf -8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JMpAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7t -UCemDaYj+bvLpgcUQg== ------END CERTIFICATE----- - -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----- - -Verisign Class 3 Public Primary Certification Authority -======================================================= ------BEGIN CERTIFICATE----- -MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMx -FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmltYXJ5 -IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVow -XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAz -IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA -A4GNADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhEBarsAx94 -f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/isI19wKTakyYbnsZogy1Ol -hec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0GCSqGSIb3DQEBAgUAA4GBALtMEivPLCYA -TxQT3ab7/AoRhIzzKBxnki98tsX63/Dolbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59Ah -WM1pF+NEHJwZRDmJXNycAA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2Omuf -Tqj/ZA1k ------END CERTIFICATE----- - -Verisign Class 3 Public Primary Certification Authority - G2 -============================================================ ------BEGIN CERTIFICATE----- -MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJBgNVBAYTAlVT -MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFy -eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln -biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz -dCBOZXR3b3JrMB4XDTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVT -MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFy -eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln -biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz -dCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCO -FoUgRm1HP9SFIIThbbP4pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71 -lSk8UOg013gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwIDAQAB -MA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSkU01UbSuvDV1Ai2TT -1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7iF6YM40AIOw7n60RzKprxaZLvcRTD -Oaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpYoJ2daZH9 ------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----- - -ValiCert Class 1 VA -=================== ------BEGIN CERTIFICATE----- -MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp -b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs -YXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh -bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNTIy -MjM0OFoXDTE5MDYyNTIyMjM0OFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0 -d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDEg -UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0 -LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA -A4GNADCBiQKBgQDYWYJ6ibiWuqYvaG9YLqdUHAZu9OqNSLwxlBfw8068srg1knaw0KWlAdcAAxIi -GQj4/xEjm84H9b9pGib+TunRf50sQB1ZaG6m+FiwnRqP0z/x3BkGgagO4DrdyFNFCQbmD3DD+kCm -DuJWBQ8YTfwggtFzVXSNdnKgHZ0dwN0/cQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFBoPUn0LBwG -lN+VYH+Wexf+T3GtZMjdd9LvWVXoP+iOBSoh8gfStadS/pyxtuJbdxdA6nLWI8sogTLDAHkY7FkX -icnGah5xyf23dKUlRWnFSKsZ4UWKJWsZ7uW7EvV/96aNUcPwnXS3qT6gpf+2SQMT2iLM7XGCK5nP -Orf1LXLI ------END CERTIFICATE----- - -ValiCert Class 2 VA -=================== ------BEGIN CERTIFICATE----- -MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp -b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs -YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh -bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAw -MTk1NFoXDTE5MDYyNjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0 -d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIg -UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0 -LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA -A4GNADCBiQKBgQDOOnHK5avIWZJV16vYdA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVC -CSRrCl6zfN1SLUzm1NZ9WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7Rf -ZHM047QSv4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9vUJSZ -SWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTuIYEZoDJJKPTEjlbV -UjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwCW/POuZ6lcg5Ktz885hZo+L7tdEy8 -W9ViH0Pd ------END CERTIFICATE----- - -RSA Root Certificate 1 -====================== ------BEGIN CERTIFICATE----- -MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp -b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs -YXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh -bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAw -MjIzM1oXDTE5MDYyNjAwMjIzM1owgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0 -d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDMg -UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0 -LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA -A4GNADCBiQKBgQDjmFGWHOjVsQaBalfDcnWTq8+epvzzFlLWLU2fNUSoLgRNB0mKOCn1dzfnt6td -3zZxFJmP3MKS8edgkpfs2Ejcv8ECIMYkpChMMFp2bbFc893enhBxoYjHW5tBbcqwuI4V7q0zK89H -BFx1cQqYJJgpp0lZpd34t0NiYfPT4tBVPwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFa7AliEZwgs -3x/be0kz9dNnnfS0ChCzycUs4pJqcXgn8nCDQtM+z6lU9PHYkhaM0QTLS6vJn0WuPIqpsHEzXcjF -V9+vqDWzf4mH6eglkrh/hXqu1rweN1gqZ8mRzyqBPu3GOd/APhmcGcwTTYJBtYze4D1gCCAPRX5r -on+jjBXu ------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----- - -Verisign Class 4 Public Primary Certification Authority - G3 -============================================================ ------BEGIN CERTIFICATE----- -MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV -UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv -cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl -IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh -dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw -CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy -dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv -cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDQgUHVibGljIFByaW1hcnkg -Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAK3LpRFpxlmr8Y+1GQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaS -tBO3IFsJ+mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0GbdU6LM -8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLmNxdLMEYH5IBtptiW -Lugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XYufTsgsbSPZUd5cBPhMnZo0QoBmrX -Razwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA -j/ola09b5KROJ1WrIhVZPMq1CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXtt -mhwwjIDLk5Mqg6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm -fjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c2NU8Qh0XwRJd -RTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/bLvSHgCwIe34QWKCudiyxLtG -UPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg== ------END CERTIFICATE----- - -Entrust.net Secure Server CA -============================ ------BEGIN CERTIFICATE----- -MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMCVVMxFDASBgNV -BAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5uZXQvQ1BTIGluY29ycC4gYnkg -cmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRl -ZDE6MDgGA1UEAxMxRW50cnVzdC5uZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhv -cml0eTAeFw05OTA1MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIG -A1UEChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBi -eSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1p -dGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24gQXV0 -aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQ -aO2f55M28Qpku0f1BBc/I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5 -gXpa0zf3wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OCAdcw -ggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHboIHYpIHVMIHSMQsw -CQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5l -dC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF -bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENl -cnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu -dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0MFqBDzIwMTkw -NTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8BdiE1U9s/8KAGv7UISX8+1i0Bow -HQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAaMAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EA -BAwwChsEVjQuMAMCBJAwDQYJKoZIhvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyN -Ewr75Ji174z4xRAN95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9 -n9cd2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI= ------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----- - -Equifax Secure Global eBusiness CA -================================== ------BEGIN CERTIFICATE----- -MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT -RXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBTZWN1cmUgR2xvYmFsIGVCdXNp -bmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIwMDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMx -HDAaBgNVBAoTE0VxdWlmYXggU2VjdXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEds -b2JhbCBlQnVzaW5lc3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRV -PEnCUdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc58O/gGzN -qfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/o5brhTMhHD4ePmBudpxn -hcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAHMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j -BBgwFoAUvqigdHJQa0S3ySPY+6j/s1draGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hs -MA0GCSqGSIb3DQEBBAUAA4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okEN -I7SS+RkAZ70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv8qIY -NMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV ------END CERTIFICATE----- - -Equifax Secure eBusiness CA 1 -============================= ------BEGIN CERTIFICATE----- -MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT -RXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENB -LTEwHhcNOTkwNjIxMDQwMDAwWhcNMjAwNjIxMDQwMDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UE -ChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNz -IENBLTEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fek6lfWg0XTzQaDJj0ItlZ -1MRoRvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5/VGcqiTZ9J2DKocKIdMSODRsjQBuWqDZQu4a -IZX5UkxVWsUPOE9G+m34LjXWHXzr4vCwdYDIqROsvojvOm6rXyo4YgKwEnv+j6YDAgMBAAGjZjBk -MBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFEp4MlIR21kW -Nl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRKeDJSEdtZFjZe38EUNkBqR3xMoTANBgkqhkiG9w0BAQQF -AAOBgQB1W6ibAxHm6VZMzfmpTMANmvPMZWnmJXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5 -lSE/9dR+WB5Hh1Q+WKG1tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN/Bf+ -KpYrtWKmpj29f5JZzVoqgrI3eQ== ------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----- - -America Online Root Certification Authority 1 -============================================= ------BEGIN CERTIFICATE----- -MIIDpDCCAoygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT -QW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBPbmxpbmUgUm9vdCBDZXJ0aWZp -Y2F0aW9uIEF1dGhvcml0eSAxMB4XDTAyMDUyODA2MDAwMFoXDTM3MTExOTIwNDMwMFowYzELMAkG -A1UEBhMCVVMxHDAaBgNVBAoTE0FtZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2Eg -T25saW5lIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMTCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBAKgv6KRpBgNHw+kqmP8ZonCaxlCyfqXfaE0bfA+2l2h9LaaLl+lkhsmj76CG -v2BlnEtUiMJIxUo5vxTjWVXlGbR0yLQFOVwWpeKVBeASrlmLojNoWBym1BW32J/X3HGrfpq/m44z -DyL9Hy7nBzbvYjnF3cu6JRQj3gzGPTzOggjmZj7aUTsWOqMFf6Dch9Wc/HKpoH145LcxVR5lu9Rh -sCFg7RAycsWSJR74kEoYeEfffjA3PlAb2xzTa5qGUwew76wGePiEmf4hjUyAtgyC9mZweRrTT6PP -8c9GsEsPPt2IYriMqQkoO3rHl+Ee5fSfwMCuJKDIodkP1nsmgmkyPacCAwEAAaNjMGEwDwYDVR0T -AQH/BAUwAwEB/zAdBgNVHQ4EFgQUAK3Zo/Z59m50qX8zPYEX10zPM94wHwYDVR0jBBgwFoAUAK3Z -o/Z59m50qX8zPYEX10zPM94wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBBQUAA4IBAQB8itEf -GDeC4Liwo+1WlchiYZwFos3CYiZhzRAW18y0ZTTQEYqtqKkFZu90821fnZmv9ov761KyBZiibyrF -VL0lvV+uyIbqRizBs73B6UlwGBaXCBOMIOAbLjpHyx7kADCVW/RFo8AasAFOq73AI25jP4BKxQft -3OJvx8Fi8eNy1gTIdGcL+oiroQHIb/AUr9KZzVGTfu0uOMe9zkZQPXLjeSWdm4grECDdpbgyn43g -Kd8hdIaC2y+CMMbHNYaz+ZZfRtsMRf3zUMNvxsNIrUam4SdHCh0Om7bCd39j8uB9Gr784N/Xx6ds -sPmuujz9dLQR6FgNgLzTqIA6me11zEZ7 ------END CERTIFICATE----- - -America Online Root Certification Authority 2 -============================================= ------BEGIN CERTIFICATE----- -MIIFpDCCA4ygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT -QW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBPbmxpbmUgUm9vdCBDZXJ0aWZp -Y2F0aW9uIEF1dGhvcml0eSAyMB4XDTAyMDUyODA2MDAwMFoXDTM3MDkyOTE0MDgwMFowYzELMAkG -A1UEBhMCVVMxHDAaBgNVBAoTE0FtZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2Eg -T25saW5lIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMjCCAiIwDQYJKoZIhvcNAQEBBQAD -ggIPADCCAgoCggIBAMxBRR3pPU0Q9oyxQcngXssNt79Hc9PwVU3dxgz6sWYFas14tNwC206B89en -fHG8dWOgXeMHDEjsJcQDIPT/DjsS/5uN4cbVG7RtIuOx238hZK+GvFciKtZHgVdEglZTvYYUAQv8 -f3SkWq7xuhG1m1hagLQ3eAkzfDJHA1zEpYNI9FdWboE2JxhP7JsowtS013wMPgwr38oE18aO6lhO -qKSlGBxsRZijQdEt0sdtjRnxrXm3gT+9BoInLRBYBbV4Bbkv2wxrkJB+FFk4u5QkE+XRnRTf04JN -RvCAOVIyD+OEsnpD8l7eXz8d3eOyG6ChKiMDbi4BFYdcpnV1x5dhvt6G3NRI270qv0pV2uh9UPu0 -gBe4lL8BPeraunzgWGcXuVjgiIZGZ2ydEEdYMtA1fHkqkKJaEBEjNa0vzORKW6fIJ/KD3l67Xnfn -6KVuY8INXWHQjNJsWiEOyiijzirplcdIz5ZvHZIlyMbGwcEMBawmxNJ10uEqZ8A9W6Wa6897Gqid -FEXlD6CaZd4vKL3Ob5Rmg0gp2OpljK+T2WSfVVcmv2/LNzGZo2C7HK2JNDJiuEMhBnIMoVxtRsX6 -Kc8w3onccVvdtjc+31D1uAclJuW8tf48ArO3+L5DwYcRlJ4jbBeKuIonDFRH8KmzwICMoCfrHRnj -B453cMor9H124HhnAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFE1FwWg4u3Op -aaEg5+31IqEjFNeeMB8GA1UdIwQYMBaAFE1FwWg4u3OpaaEg5+31IqEjFNeeMA4GA1UdDwEB/wQE -AwIBhjANBgkqhkiG9w0BAQUFAAOCAgEAZ2sGuV9FOypLM7PmG2tZTiLMubekJcmnxPBUlgtk87FY -T15R/LKXeydlwuXK5w0MJXti4/qftIe3RUavg6WXSIylvfEWK5t2LHo1YGwRgJfMqZJS5ivmae2p -+DYtLHe/YUjRYwu5W1LtGLBDQiKmsXeu3mnFzcccobGlHBD7GL4acN3Bkku+KVqdPzW+5X1R+FXg -JXUjhx5c3LqdsKyzadsXg8n33gy8CNyRnqjQ1xU3c6U1uPx+xURABsPr+CKAXEfOAuMRn0T//Zoy -zH1kUQ7rVyZ2OuMeIjzCpjbdGe+n/BLzJsBZMYVMnNjP36TMzCmT/5RtdlwTCJfy7aULTd3oyWgO -ZtMADjMSW7yV5TKQqLPGbIOtd+6Lfn6xqavT4fG2wLHqiMDn05DpKJKUe2h7lyoKZy2FAjgQ5ANh -1NolNscIWC2hp1GvMApJ9aZphwctREZ2jirlmjvXGKL8nDgQzMY70rUXOm/9riW99XJZZLF0Kjhf -GEzfz3EEWjbUvy+ZnOjZurGV5gJLIaFb1cFPj65pbVPbAZO1XB4Y3WRayhgoPmMEEf0cjQAPuDff -Z4qdZqkCapH/E8ovXYO8h5Ns3CRRFgQlZvqz2cK6Kb6aSDiCmfS/O0oxGfm/jiEzFMpPVF/7zvuP -cX/9XhmgD0uRuMRUvAawRY8mkaKO/qk= ------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----- - -TDC Internet Root CA -==================== ------BEGIN CERTIFICATE----- -MIIEKzCCAxOgAwIBAgIEOsylTDANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJESzEVMBMGA1UE -ChMMVERDIEludGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQgUm9vdCBDQTAeFw0wMTA0MDUx -NjMzMTdaFw0yMTA0MDUxNzAzMTdaMEMxCzAJBgNVBAYTAkRLMRUwEwYDVQQKEwxUREMgSW50ZXJu -ZXQxHTAbBgNVBAsTFFREQyBJbnRlcm5ldCBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEAxLhAvJHVYx/XmaCLDEAedLdInUaMArLgJF/wGROnN4NrXceO+YQwzho7+vvOi20j -xsNuZp+Jpd/gQlBn+h9sHvTQBda/ytZO5GhgbEaqHF1j4QeGDmUApy6mcca8uYGoOn0a0vnRrEvL -znWv3Hv6gXPU/Lq9QYjUdLP5Xjg6PEOo0pVOd20TDJ2PeAG3WiAfAzc14izbSysseLlJ28TQx5yc -5IogCSEWVmb/Bexb4/DPqyQkXsN/cHoSxNK1EKC2IeGNeGlVRGn1ypYcNIUXJXfi9i8nmHj9eQY6 -otZaQ8H/7AQ77hPv01ha/5Lr7K7a8jcDR0G2l8ktCkEiu7vmpwIDAQABo4IBJTCCASEwEQYJYIZI -AYb4QgEBBAQDAgAHMGUGA1UdHwReMFwwWqBYoFakVDBSMQswCQYDVQQGEwJESzEVMBMGA1UEChMM -VERDIEludGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQgUm9vdCBDQTENMAsGA1UEAxMEQ1JM -MTArBgNVHRAEJDAigA8yMDAxMDQwNTE2MzMxN1qBDzIwMjEwNDA1MTcwMzE3WjALBgNVHQ8EBAMC -AQYwHwYDVR0jBBgwFoAUbGQBx/2FbazI2p5QCIUItTxWqFAwHQYDVR0OBBYEFGxkAcf9hW2syNqe -UAiFCLU8VqhQMAwGA1UdEwQFMAMBAf8wHQYJKoZIhvZ9B0EABBAwDhsIVjUuMDo0LjADAgSQMA0G -CSqGSIb3DQEBBQUAA4IBAQBOQ8zR3R0QGwZ/t6T609lN+yOfI1Rb5osvBCiLtSdtiaHsmGnc540m -gwV5dOy0uaOXwTUA/RXaOYE6lTGQ3pfphqiZdwzlWqCE/xIWrG64jcN7ksKsLtB9KOy282A4aW8+ -2ARVPp7MVdK6/rtHBNcK2RYKNCn1WBPVT8+PVkuzHu7TmHnaCB4Mb7j4Fifvwm899qNLPg7kbWzb -O0ESm70NRyN/PErQr8Cv9u8btRXE64PECV90i9kR+8JWsTz4cMo0jUNAE4z9mQNUecYu6oah9jrU -Cbz0vGbMPVjQV0kK7iXiQe4T+Zs4NNEA9X7nlB38aQNiuJkFBT1reBK9sG9l ------END CERTIFICATE----- - -UTN DATACorp SGC Root CA -======================== ------BEGIN CERTIFICATE----- -MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCBkzELMAkGA1UE -BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl -IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZ -BgNVBAMTElVUTiAtIERBVEFDb3JwIFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBa -MIGTMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4w -HAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRy -dXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjANBgkqhkiG9w0BAQEFAAOC -AQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ys -raP6LnD43m77VkIVni5c7yPeIbkFdicZD0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlo -wHDyUwDAXlCCpVZvNvlK4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA -9P4yPykqlXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulWbfXv -33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQABo4GrMIGoMAsGA1Ud -DwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRTMtGzz3/64PGgXYVOktKeRR20TzA9 -BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3JsLnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dD -LmNybDAqBgNVHSUEIzAhBggrBgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3 -DQEBBQUAA4IBAQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft -Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyjj98C5OBxOvG0 -I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVHKWss5nbZqSl9Mt3JNjy9rjXx -EZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwP -DPafepE39peC4N1xaf92P2BNPM/3mfnGV/TJVTl4uix5yaaIK/QI ------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----- - -NetLock Business (Class B) Root -=============================== ------BEGIN CERTIFICATE----- -MIIFSzCCBLSgAwIBAgIBaTANBgkqhkiG9w0BAQQFADCBmTELMAkGA1UEBhMCSFUxETAPBgNVBAcT -CEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0b25zYWdpIEtmdC4xGjAYBgNV -BAsTEVRhbnVzaXR2YW55a2lhZG9rMTIwMAYDVQQDEylOZXRMb2NrIFV6bGV0aSAoQ2xhc3MgQikg -VGFudXNpdHZhbnlraWFkbzAeFw05OTAyMjUxNDEwMjJaFw0xOTAyMjAxNDEwMjJaMIGZMQswCQYD -VQQGEwJIVTERMA8GA1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRv -bnNhZ2kgS2Z0LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxMjAwBgNVBAMTKU5ldExvY2sg -VXpsZXRpIChDbGFzcyBCKSBUYW51c2l0dmFueWtpYWRvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB -iQKBgQCx6gTsIKAjwo84YM/HRrPVG/77uZmeBNwcf4xKgZjupNTKihe5In+DCnVMm8Bp2GQ5o+2S -o/1bXHQawEfKOml2mrriRBf8TKPV/riXiK+IA4kfpPIEPsgHC+b5sy96YhQJRhTKZPWLgLViqNhr -1nGTLbO/CVRY7QbrqHvcQ7GhaQIDAQABo4ICnzCCApswEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNV -HQ8BAf8EBAMCAAYwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaCAk1GSUdZ -RUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pvbGdhbHRh -dGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQuIEEgaGl0 -ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2VnLWJpenRv -c2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUg -YXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJh -c2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBhIGh0dHBz -Oi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVub3J6ZXNA -bmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1YW5jZSBhbmQgdGhl -IHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sgQ1BTIGF2 -YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBj -cHNAbmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4GBAATbrowXr/gOkDFOzT4JwG06sPgzTEdM -43WIEJessDgVkcYplswhwG08pXTP2IKlOcNl40JwuyKQ433bNXbhoLXan3BukxowOR0w2y7jfLKR -stE3Kfq51hdcR0/jHTjrn9V7lagonhVK0dHQKwCXoOKSNitjrFgBazMpUIaD8QFI ------END CERTIFICATE----- - -NetLock Express (Class C) Root -============================== ------BEGIN CERTIFICATE----- -MIIFTzCCBLigAwIBAgIBaDANBgkqhkiG9w0BAQQFADCBmzELMAkGA1UEBhMCSFUxETAPBgNVBAcT -CEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0b25zYWdpIEtmdC4xGjAYBgNV -BAsTEVRhbnVzaXR2YW55a2lhZG9rMTQwMgYDVQQDEytOZXRMb2NrIEV4cHJlc3N6IChDbGFzcyBD -KSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNTE0MDgxMVoXDTE5MDIyMDE0MDgxMVowgZsxCzAJ -BgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6 -dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE0MDIGA1UEAxMrTmV0TG9j -ayBFeHByZXNzeiAoQ2xhc3MgQykgVGFudXNpdHZhbnlraWFkbzCBnzANBgkqhkiG9w0BAQEFAAOB -jQAwgYkCgYEA6+ywbGGKIyWvYCDj2Z/8kwvbXY2wobNAOoLO/XXgeDIDhlqGlZHtU/qdQPzm6N3Z -W3oDvV3zOwzDUXmbrVWg6dADEK8KuhRC2VImESLH0iDMgqSaqf64gXadarfSNnU+sYYJ9m5tfk63 -euyucYT2BDMIJTLrdKwWRMbkQJMdf60CAwEAAaOCAp8wggKbMBIGA1UdEwEB/wQIMAYBAf8CAQQw -DgYDVR0PAQH/BAQDAgAGMBEGCWCGSAGG+EIBAQQEAwIABzCCAmAGCWCGSAGG+EIBDQSCAlEWggJN -RklHWUVMRU0hIEV6ZW4gdGFudXNpdHZhbnkgYSBOZXRMb2NrIEtmdC4gQWx0YWxhbm9zIFN6b2xn -YWx0YXRhc2kgRmVsdGV0ZWxlaWJlbiBsZWlydCBlbGphcmFzb2sgYWxhcGphbiBrZXN6dWx0LiBB -IGhpdGVsZXNpdGVzIGZvbHlhbWF0YXQgYSBOZXRMb2NrIEtmdC4gdGVybWVrZmVsZWxvc3NlZy1i -aXp0b3NpdGFzYSB2ZWRpLiBBIGRpZ2l0YWxpcyBhbGFpcmFzIGVsZm9nYWRhc2FuYWsgZmVsdGV0 -ZWxlIGF6IGVsb2lydCBlbGxlbm9yemVzaSBlbGphcmFzIG1lZ3RldGVsZS4gQXogZWxqYXJhcyBs -ZWlyYXNhIG1lZ3RhbGFsaGF0byBhIE5ldExvY2sgS2Z0LiBJbnRlcm5ldCBob25sYXBqYW4gYSBo -dHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIGNpbWVuIHZhZ3kga2VyaGV0byBheiBlbGxlbm9y -emVzQG5ldGxvY2submV0IGUtbWFpbCBjaW1lbi4gSU1QT1JUQU5UISBUaGUgaXNzdWFuY2UgYW5k -IHRoZSB1c2Ugb2YgdGhpcyBjZXJ0aWZpY2F0ZSBpcyBzdWJqZWN0IHRvIHRoZSBOZXRMb2NrIENQ -UyBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cubmV0bG9jay5uZXQvZG9jcyBvciBieSBlLW1haWwg -YXQgY3BzQG5ldGxvY2submV0LjANBgkqhkiG9w0BAQQFAAOBgQAQrX/XDDKACtiG8XmYta3UzbM2 -xJZIwVzNmtkFLp++UOv0JhQQLdRmF/iewSf98e3ke0ugbLWrmldwpu2gpO0u9f38vf5NNwgMvOOW -gyL1SRt/Syu0VMGAfJlOHdCM7tCs5ZL6dVb+ZKATj7i4Fp1hBWeAyNDYpQcCNJgEjTME1A== ------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----- - -TURKTRUST Certificate Services Provider Root 1 -============================================== ------BEGIN CERTIFICATE----- -MIID+zCCAuOgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBtzE/MD0GA1UEAww2VMOcUktUUlVTVCBF -bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGDAJUUjEP -MA0GA1UEBwwGQU5LQVJBMVYwVAYDVQQKDE0oYykgMjAwNSBUw5xSS1RSVVNUIEJpbGdpIMSwbGV0 -acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjAeFw0wNTA1MTMx -MDI3MTdaFw0xNTAzMjIxMDI3MTdaMIG3MT8wPQYDVQQDDDZUw5xSS1RSVVNUIEVsZWt0cm9uaWsg -U2VydGlmaWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLExCzAJBgNVBAYMAlRSMQ8wDQYDVQQHDAZB -TktBUkExVjBUBgNVBAoMTShjKSAyMDA1IFTDnFJLVFJVU1QgQmlsZ2kgxLBsZXRpxZ9pbSB2ZSBC -aWxpxZ9pbSBHw7x2ZW5sacSfaSBIaXptZXRsZXJpIEEuxZ4uMIIBIjANBgkqhkiG9w0BAQEFAAOC -AQ8AMIIBCgKCAQEAylIF1mMD2Bxf3dJ7XfIMYGFbazt0K3gNfUW9InTojAPBxhEqPZW8qZSwu5GX -yGl8hMW0kWxsE2qkVa2kheiVfrMArwDCBRj1cJ02i67L5BuBf5OI+2pVu32Fks66WJ/bMsW9Xe8i -Si9BB35JYbOG7E6mQW6EvAPs9TscyB/C7qju6hJKjRTP8wrgUDn5CDX4EVmt5yLqS8oUBt5CurKZ -8y1UiBAG6uEaPj1nH/vO+3yC6BFdSsG5FOpU2WabfIl9BJpiyelSPJ6c79L1JuTm5Rh8i27fbMx4 -W09ysstcP4wFjdFMjK2Sx+F4f2VsSQZQLJ4ywtdKxnWKWU51b0dewQIDAQABoxAwDjAMBgNVHRME -BTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAV9VX/N5aAWSGk/KEVTCD21F/aAyT8z5Aa9CEKmu46 -sWrv7/hg0Uw2ZkUd82YCdAR7kjCo3gp2D++Vbr3JN+YaDayJSFvMgzbC9UZcWYJWtNX+I7TYVBxE -q8Sn5RTOPEFhfEPmzcSBCYsk+1Ql1haolgxnB2+zUEfjHCQo3SqYpGH+2+oSN7wBGjSFvW5P55Fy -B0SFHljKVETd96y5y4khctuPwGkplyqjrhgjlxxBKot8KsF8kOipKMDTkcatKIdAaLX/7KfS0zgY -nNN9aV3wxqUeJBujR/xpB2jn5Jq07Q+hh4cCzofSSE7hvP/L8XKSRGQDJereW26fyfJOrN3H ------END CERTIFICATE----- - -TURKTRUST Certificate Services Provider Root 2 -============================================== ------BEGIN CERTIFICATE----- -MIIEPDCCAySgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBF -bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEP -MA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUg -QmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwHhcN -MDUxMTA3MTAwNzU3WhcNMTUwOTE2MTAwNzU3WjCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBFbGVr -dHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEPMA0G -A1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmls -acWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCpNn7DkUNMwxmYCMjHWHtPFoylzkkBH3MOrHUTpvqe -LCDe2JAOCtFp0if7qnefJ1Il4std2NiDUBd9irWCPwSOtNXwSadktx4uXyCcUHVPr+G1QRT0mJKI -x+XlZEdhR3n9wFHxwZnn3M5q+6+1ATDcRhzviuyV79z/rxAc653YsKpqhRgNF8k+v/Gb0AmJQv2g -QrSdiVFVKc8bcLyEVK3BEx+Y9C52YItdP5qtygy/p1Zbj3e41Z55SZI/4PGXJHpsmxcPbe9TmJEr -5A++WXkHeLuXlfSfadRYhwqp48y2WBmfJiGxxFmNskF1wK1pzpwACPI2/z7woQ8arBT9pmAPAgMB -AAGjQzBBMB0GA1UdDgQWBBTZN7NOBf3Zz58SFq62iS/rJTqIHDAPBgNVHQ8BAf8EBQMDBwYAMA8G -A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAHJglrfJ3NgpXiOFX7KzLXb7iNcX/ntt -Rbj2hWyfIvwqECLsqrkw9qtY1jkQMZkpAL2JZkH7dN6RwRgLn7Vhy506vvWolKMiVW4XSf/SKfE4 -Jl3vpao6+XF75tpYHdN0wgH6PmlYX63LaL4ULptswLbcoCb6dxriJNoaN+BnrdFzgw2lGh1uEpJ+ -hGIAF728JRhX8tepb1mIvDS3LoV4nZbcFMMsilKbloxSZj2GFotHuFEJjOp9zYhys2AzsfAKRO8P -9Qk3iCQOLGsgOqL6EfJANZxEaGM7rDNvY7wsu/LSy3Z9fYjYHcgFHW68lKlmjHdxx/qR+i9Rnuk5 -UrbnBEI= ------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----- - -AC Ra\xC3\xADz Certic\xC3\xA1mara S.A. -====================================== ------BEGIN CERTIFICATE----- -MIIGZjCCBE6gAwIBAgIPB35Sk3vgFeNX8GmMy+wMMA0GCSqGSIb3DQEBBQUAMHsxCzAJBgNVBAYT -AkNPMUcwRQYDVQQKDD5Tb2NpZWRhZCBDYW1lcmFsIGRlIENlcnRpZmljYWNpw7NuIERpZ2l0YWwg -LSBDZXJ0aWPDoW1hcmEgUy5BLjEjMCEGA1UEAwwaQUMgUmHDrXogQ2VydGljw6FtYXJhIFMuQS4w -HhcNMDYxMTI3MjA0NjI5WhcNMzAwNDAyMjE0MjAyWjB7MQswCQYDVQQGEwJDTzFHMEUGA1UECgw+ -U29jaWVkYWQgQ2FtZXJhbCBkZSBDZXJ0aWZpY2FjacOzbiBEaWdpdGFsIC0gQ2VydGljw6FtYXJh -IFMuQS4xIzAhBgNVBAMMGkFDIFJhw616IENlcnRpY8OhbWFyYSBTLkEuMIICIjANBgkqhkiG9w0B -AQEFAAOCAg8AMIICCgKCAgEAq2uJo1PMSCMI+8PPUZYILrgIem08kBeGqentLhM0R7LQcNzJPNCN -yu5LF6vQhbCnIwTLqKL85XXbQMpiiY9QngE9JlsYhBzLfDe3fezTf3MZsGqy2IiKLUV0qPezuMDU -2s0iiXRNWhU5cxh0T7XrmafBHoi0wpOQY5fzp6cSsgkiBzPZkc0OnB8OIMfuuzONj8LSWKdf/WU3 -4ojC2I+GdV75LaeHM/J4Ny+LvB2GNzmxlPLYvEqcgxhaBvzz1NS6jBUJJfD5to0EfhcSM2tXSExP -2yYe68yQ54v5aHxwD6Mq0Do43zeX4lvegGHTgNiRg0JaTASJaBE8rF9ogEHMYELODVoqDA+bMMCm -8Ibbq0nXl21Ii/kDwFJnmxL3wvIumGVC2daa49AZMQyth9VXAnow6IYm+48jilSH5L887uvDdUhf -HjlvgWJsxS3EF1QZtzeNnDeRyPYL1epjb4OsOMLzP96a++EjYfDIJss2yKHzMI+ko6Kh3VOz3vCa -Mh+DkXkwwakfU5tTohVTP92dsxA7SH2JD/ztA/X7JWR1DhcZDY8AFmd5ekD8LVkH2ZD6mq093ICK -5lw1omdMEWux+IBkAC1vImHFrEsm5VoQgpukg3s0956JkSCXjrdCx2bD0Omk1vUgjcTDlaxECp1b -czwmPS9KvqfJpxAe+59QafMCAwEAAaOB5jCB4zAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE -AwIBBjAdBgNVHQ4EFgQU0QnQ6dfOeXRU+Tows/RtLAMDG2gwgaAGA1UdIASBmDCBlTCBkgYEVR0g -ADCBiTArBggrBgEFBQcCARYfaHR0cDovL3d3dy5jZXJ0aWNhbWFyYS5jb20vZHBjLzBaBggrBgEF -BQcCAjBOGkxMaW1pdGFjaW9uZXMgZGUgZ2FyYW507WFzIGRlIGVzdGUgY2VydGlmaWNhZG8gc2Ug -cHVlZGVuIGVuY29udHJhciBlbiBsYSBEUEMuMA0GCSqGSIb3DQEBBQUAA4ICAQBclLW4RZFNjmEf -AygPU3zmpFmps4p6xbD/CHwso3EcIRNnoZUSQDWDg4902zNc8El2CoFS3UnUmjIz75uny3XlesuX -EpBcunvFm9+7OSPI/5jOCk0iAUgHforA1SBClETvv3eiiWdIG0ADBaGJ7M9i4z0ldma/Jre7Ir5v -/zlXdLp6yQGVwZVR6Kss+LGGIOk/yzVb0hfpKv6DExdA7ohiZVvVO2Dpezy4ydV/NgIlqmjCMRW3 -MGXrfx1IebHPOeJCgBbT9ZMj/EyXyVo3bHwi2ErN0o42gzmRkBDI8ck1fj+404HGIGQatlDCIaR4 -3NAvO2STdPCWkPHv+wlaNECW8DYSwaN0jJN+Qd53i+yG2dIPPy3RzECiiWZIHiCznCNZc6lEc7wk -eZBWN7PGKX6jD/EpOe9+XCgycDWs2rjIdWb8m0w5R44bb5tNAlQiM+9hup4phO9OSzNHdpdqy35f -/RWmnkJDW2ZaiogN9xa5P1FlK2Zqi9E4UqLWRhH6/JocdJ6PlwsCT2TG9WjTSy3/pDceiz+/RL5h -RqGEPQgnTIEgd4kI6mdAXmwIUV80WoyWaM3X94nCHNMyAK9Sy9NgWyo6R35rMDOhYil/SrnhLecU -Iw4OGEfhefwVVdCx/CVxY3UzHCMrr1zZ7Ud3YA47Dx7SwNxkBYn8eNZcLCZDqQ== ------END CERTIFICATE----- - -TC TrustCenter Class 2 CA II -============================ ------BEGIN CERTIFICATE----- -MIIEqjCCA5KgAwIBAgIOLmoAAQACH9dSISwRXDswDQYJKoZIhvcNAQEFBQAwdjELMAkGA1UEBhMC -REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNVBAsTGVRDIFRydXN0Q2VudGVy -IENsYXNzIDIgQ0ExJTAjBgNVBAMTHFRDIFRydXN0Q2VudGVyIENsYXNzIDIgQ0EgSUkwHhcNMDYw -MTEyMTQzODQzWhcNMjUxMjMxMjI1OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1 -c3RDZW50ZXIgR21iSDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQTElMCMGA1UE -AxMcVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC -AQoCggEBAKuAh5uO8MN8h9foJIIRszzdQ2Lu+MNF2ujhoF/RKrLqk2jftMjWQ+nEdVl//OEd+DFw -IxuInie5e/060smp6RQvkL4DUsFJzfb95AhmC1eKokKguNV/aVyQMrKXDcpK3EY+AlWJU+MaWss2 -xgdW94zPEfRMuzBwBJWl9jmM/XOBCH2JXjIeIqkiRUuwZi4wzJ9l/fzLganx4Duvo4bRierERXlQ -Xa7pIXSSTYtZgo+U4+lK8edJsBTj9WLL1XK9H7nSn6DNqPoByNkN39r8R52zyFTfSUrxIan+GE7u -SNQZu+995OKdy1u2bv/jzVrndIIFuoAlOMvkaZ6vQaoahPUCAwEAAaOCATQwggEwMA8GA1UdEwEB -/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTjq1RMgKHbVkO3kUrL84J6E1wIqzCB -7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRydXN0Y2VudGVyLmRlL2NybC92Mi90 -Y19jbGFzc18yX2NhX0lJLmNybIaBn2xkYXA6Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBU -cnVzdENlbnRlciUyMENsYXNzJTIwMiUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21i -SCxPVT1yb290Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u -TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEAjNfffu4bgBCzg/XbEeprS6iSGNn3Bzn1LL4G -dXpoUxUc6krtXvwjshOg0wn/9vYua0Fxec3ibf2uWWuFHbhOIprtZjluS5TmVfwLG4t3wVMTZonZ -KNaL80VKY7f9ewthXbhtvsPcW3nS7Yblok2+XnR8au0WOB9/WIFaGusyiC2y8zl3gK9etmF1Kdsj -TYjKUCjLhdLTEKJZbtOTVAB6okaVhgWcqRmY5TFyDADiZ9lA4CQze28suVyrZZ0srHbqNZn1l7kP -JOzHdiEoZa5X6AeIdUpWoNIFOqTmjZKILPPy4cHGYdtBxceb9w4aUUXCYWvcZCcXjFq32nQozZfk -vQ== ------END CERTIFICATE----- - -TC TrustCenter Class 3 CA II -============================ ------BEGIN CERTIFICATE----- -MIIEqjCCA5KgAwIBAgIOSkcAAQAC5aBd1j8AUb8wDQYJKoZIhvcNAQEFBQAwdjELMAkGA1UEBhMC -REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNVBAsTGVRDIFRydXN0Q2VudGVy -IENsYXNzIDMgQ0ExJTAjBgNVBAMTHFRDIFRydXN0Q2VudGVyIENsYXNzIDMgQ0EgSUkwHhcNMDYw -MTEyMTQ0MTU3WhcNMjUxMjMxMjI1OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1 -c3RDZW50ZXIgR21iSDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQTElMCMGA1UE -AxMcVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC -AQoCggEBALTgu1G7OVyLBMVMeRwjhjEQY0NVJz/GRcekPewJDRoeIMJWHt4bNwcwIi9v8Qbxq63W -yKthoy9DxLCyLfzDlml7forkzMA5EpBCYMnMNWju2l+QVl/NHE1bWEnrDgFPZPosPIlY2C8u4rBo -6SI7dYnWRBpl8huXJh0obazovVkdKyT21oQDZogkAHhg8fir/gKya/si+zXmFtGt9i4S5Po1auUZ -uV3bOx4a+9P/FRQI2AlqukWdFHlgfa9Aigdzs5OW03Q0jTo3Kd5c7PXuLjHCINy+8U9/I1LZW+Jk -2ZyqBwi1Rb3R0DHBq1SfqdLDYmAD8bs5SpJKPQq5ncWg/jcCAwEAAaOCATQwggEwMA8GA1UdEwEB -/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTUovyfs8PYA9NXXAek0CSnwPIA1DCB -7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRydXN0Y2VudGVyLmRlL2NybC92Mi90 -Y19jbGFzc18zX2NhX0lJLmNybIaBn2xkYXA6Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBU -cnVzdENlbnRlciUyMENsYXNzJTIwMyUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21i -SCxPVT1yb290Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u -TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEANmDkcPcGIEPZIxpC8vijsrlNirTzwppVMXzE -O2eatN9NDoqTSheLG43KieHPOh6sHfGcMrSOWXaiQYUlN6AT0PV8TtXqluJucsG7Kv5sbviRmEb8 -yRtXW+rIGjs/sFGYPAfaLFkB2otE6OF0/ado3VS6g0bsyEa1+K+XwDsJHI/OcpY9M1ZwvJbL2NV9 -IJqDnxrcOfHFcqMRA/07QlIp2+gB95tejNaNhk4Z+rwcvsUhpYeeeC422wlxo3I0+GzjBgnyXlal -092Y+tTmBvTwtiBjS+opvaqCZh77gaqnN60TGOaSw4HBM7uIHqHn4rS9MWwOUT1v+5ZWgOI2F9Hc -5A== ------END CERTIFICATE----- - -TC TrustCenter Universal CA I -============================= ------BEGIN CERTIFICATE----- -MIID3TCCAsWgAwIBAgIOHaIAAQAC7LdggHiNtgYwDQYJKoZIhvcNAQEFBQAweTELMAkGA1UEBhMC -REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNVBAsTG1RDIFRydXN0Q2VudGVy -IFVuaXZlcnNhbCBDQTEmMCQGA1UEAxMdVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBIEkwHhcN -MDYwMzIyMTU1NDI4WhcNMjUxMjMxMjI1OTU5WjB5MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMg -VHJ1c3RDZW50ZXIgR21iSDEkMCIGA1UECxMbVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBMSYw -JAYDVQQDEx1UQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0EgSTCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBAKR3I5ZEr5D0MacQ9CaHnPM42Q9e3s9B6DGtxnSRJJZ4Hgmgm5qVSkr1YnwC -qMqs+1oEdjneX/H5s7/zA1hV0qq34wQi0fiU2iIIAI3TfCZdzHd55yx4Oagmcw6iXSVphU9VDprv -xrlE4Vc93x9UIuVvZaozhDrzznq+VZeujRIPFDPiUHDDSYcTvFHe15gSWu86gzOSBnWLknwSaHtw -ag+1m7Z3W0hZneTvWq3zwZ7U10VOylY0Ibw+F1tvdwxIAUMpsN0/lm7mlaoMwCC2/T42J5zjXM9O -gdwZu5GQfezmlwQek8wiSdeXhrYTCjxDI3d+8NzmzSQfO4ObNDqDNOMCAwEAAaNjMGEwHwYDVR0j -BBgwFoAUkqR1LKSevoFE63n8isWVpesQdXMwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AYYwHQYDVR0OBBYEFJKkdSyknr6BROt5/IrFlaXrEHVzMA0GCSqGSIb3DQEBBQUAA4IBAQAo0uCG -1eb4e/CX3CJrO5UUVg8RMKWaTzqwOuAGy2X17caXJ/4l8lfmXpWMPmRgFVp/Lw0BxbFg/UU1z/Cy -vwbZ71q+s2IhtNerNXxTPqYn8aEt2hojnczd7Dwtnic0XQ/CNnm8yUpiLe1r2X1BQ3y2qsrtYbE3 -ghUJGooWMNjsydZHcnhLEEYUjl8Or+zHL6sQ17bxbuyGssLoDZJz3KL0Dzq/YSMQiZxIQG5wALPT -ujdEWBF6AmqI8Dc08BnprNRlc/ZpjGSUOnmFKbAWKwyCPwacx/0QK54PLLae4xW/2TYcuiUaUj0a -7CIMHOCkoj3w6DnPgcB77V0fb8XQC9eY ------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----- - -ComSign Secured CA -================== ------BEGIN CERTIFICATE----- -MIIDqzCCApOgAwIBAgIRAMcoRwmzuGxFjB36JPU2TukwDQYJKoZIhvcNAQEFBQAwPDEbMBkGA1UE -AxMSQ29tU2lnbiBTZWN1cmVkIENBMRAwDgYDVQQKEwdDb21TaWduMQswCQYDVQQGEwJJTDAeFw0w -NDAzMjQxMTM3MjBaFw0yOTAzMTYxNTA0NTZaMDwxGzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBD -QTEQMA4GA1UEChMHQ29tU2lnbjELMAkGA1UEBhMCSUwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw -ggEKAoIBAQDGtWhfHZQVw6QIVS3joFd67+l0Kru5fFdJGhFeTymHDEjWaueP1H5XJLkGieQcPOqs -49ohgHMhCu95mGwfCP+hUH3ymBvJVG8+pSjsIQQPRbsHPaHA+iqYHU4Gk/v1iDurX8sWv+bznkqH -7Rnqwp9D5PGBpX8QTz7RSmKtUxvLg/8HZaWSLWapW7ha9B20IZFKF3ueMv5WJDmyVIRD9YTC2LxB -kMyd1mja6YJQqTtoz7VdApRgFrFD2UNd3V2Hbuq7s8lr9gOUCXDeFhF6K+h2j0kQmHe5Y1yLM5d1 -9guMsqtb3nQgJT/j8xH5h2iGNXHDHYwt6+UarA9z1YJZQIDTAgMBAAGjgacwgaQwDAYDVR0TBAUw -AwEB/zBEBgNVHR8EPTA7MDmgN6A1hjNodHRwOi8vZmVkaXIuY29tc2lnbi5jby5pbC9jcmwvQ29t -U2lnblNlY3VyZWRDQS5jcmwwDgYDVR0PAQH/BAQDAgGGMB8GA1UdIwQYMBaAFMFL7XC29z58ADsA -j8c+DkWfHl3sMB0GA1UdDgQWBBTBS+1wtvc+fAA7AI/HPg5Fnx5d7DANBgkqhkiG9w0BAQUFAAOC -AQEAFs/ukhNQq3sUnjO2QiBq1BW9Cav8cujvR3qQrFHBZE7piL1DRYHjZiM/EoZNGeQFsOY3wo3a -BijJD4mkU6l1P7CW+6tMM1X5eCZGbxs2mPtCdsGCuY7e+0X5YxtiOzkGynd6qDwJz2w2PQ8KRUtp -FhpFfTMDZflScZAmlaxMDPWLkz/MdXSFmLr/YnpNH4n+rr2UAJm/EaXc4HnFFgt9AmEd6oX5AhVP -51qJThRv4zdLhfXBPGHg/QVBspJ/wx2g0K5SZGBrGMYmnNj1ZOQ2GmKfig8+/21OGVZOIJFsnzQz -OjRXUDpvgV4GxvU+fE6OK85lBi5d0ipTdF7Tbieejw== ------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----- - -Buypass Class 3 CA 1 -==================== ------BEGIN CERTIFICATE----- -MIIDUzCCAjugAwIBAgIBAjANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU -QnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3MgQ2xhc3MgMyBDQSAxMB4XDTA1 -MDUwOTE0MTMwM1oXDTE1MDUwOTE0MTMwM1owSzELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBh -c3MgQVMtOTgzMTYzMzI3MR0wGwYDVQQDDBRCdXlwYXNzIENsYXNzIDMgQ0EgMTCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAKSO13TZKWTeXx+HgJHqTjnmGcZEC4DVC69TB4sSveZn8AKx -ifZgisRbsELRwCGoy+Gb72RRtqfPFfV0gGgEkKBYouZ0plNTVUhjP5JW3SROjvi6K//zNIqeKNc0 -n6wv1g/xpC+9UrJJhW05NfBEMJNGJPO251P7vGGvqaMU+8IXF4Rs4HyI+MkcVyzwPX6UvCWThOia -AJpFBUJXgPROztmuOfbIUxAMZTpHe2DC1vqRycZxbL2RhzyRhkmr8w+gbCZ2Xhysm3HljbybIR6c -1jh+JIAVMYKWsUnTYjdbiAwKYjT+p0h+mbEwi5A3lRyoH6UsjfRVyNvdWQrCrXig9IsCAwEAAaNC -MEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUOBTmyPCppAP0Tj4io1vy1uCtQHQwDgYDVR0P -AQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQABZ6OMySU9E2NdFm/soT4JXJEVKirZgCFPBdy7 -pYmrEzMqnji3jG8CcmPHc3ceCQa6Oyh7pEfJYWsICCD8igWKH7y6xsL+z27sEzNxZy5p+qksP2bA -EllNC1QCkoS72xLvg3BweMhT+t/Gxv/ciC8HwEmdMldg0/L2mSlf56oBzKwzqBwKu5HEA6BvtjT5 -htOzdlSY9EqBs1OdTUDs5XcTRa9bqh/YL0yCe/4qxFi7T/ye/QNlGioOw6UgFpRreaaiErS7GqQj -el/wroQk5PMr+4okoyeYZdowdXb8GZHo2+ubPzK/QJcHJrrM85SFSnonk8+QQtS4Wxam58tAA915 ------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----- - -Verisign Class 3 Public Primary Certification Authority -======================================================= ------BEGIN CERTIFICATE----- -MIICPDCCAaUCEDyRMcsf9tAbDpq40ES/Er4wDQYJKoZIhvcNAQEFBQAwXzELMAkGA1UEBhMCVVMx -FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmltYXJ5 -IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVow -XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAz -IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA -A4GNADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhEBarsAx94 -f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/isI19wKTakyYbnsZogy1Ol -hec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBABByUqkFFBky -CEHwxWsKzH4PIRnN5GfcX6kb5sroc50i2JhucwNhkcV8sEVAbkSdjbCxlnRhLQ2pRdKkkirWmnWX -bj9T/UWZYB2oK0z5XqcJ2HUw19JlYD1n1khVdWk/kfVIC0dpImmClr7JyDiGSnoscxlIaU5rfGW/ -D/xwzoiQ ------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----- - -E-Guven Kok Elektronik Sertifika Hizmet Saglayicisi -=================================================== ------BEGIN CERTIFICATE----- -MIIDtjCCAp6gAwIBAgIQRJmNPMADJ72cdpW56tustTANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQG -EwJUUjEoMCYGA1UEChMfRWxla3Ryb25payBCaWxnaSBHdXZlbmxpZ2kgQS5TLjE8MDoGA1UEAxMz -ZS1HdXZlbiBLb2sgRWxla3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhZ2xheWljaXNpMB4XDTA3 -MDEwNDExMzI0OFoXDTE3MDEwNDExMzI0OFowdTELMAkGA1UEBhMCVFIxKDAmBgNVBAoTH0VsZWt0 -cm9uaWsgQmlsZ2kgR3V2ZW5saWdpIEEuUy4xPDA6BgNVBAMTM2UtR3V2ZW4gS29rIEVsZWt0cm9u -aWsgU2VydGlmaWthIEhpem1ldCBTYWdsYXlpY2lzaTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC -AQoCggEBAMMSIJ6wXgBljU5Gu4Bc6SwGl9XzcslwuedLZYDBS75+PNdUMZTe1RK6UxYC6lhj71vY -8+0qGqpxSKPcEC1fX+tcS5yWCEIlKBHMilpiAVDV6wlTL/jDj/6z/P2douNffb7tC+Bg62nsM+3Y -jfsSSYMAyYuXjDtzKjKzEve5TfL0TW3H5tYmNwjy2f1rXKPlSFxYvEK+A1qBuhw1DADT9SN+cTAI -JjjcJRFHLfO6IxClv7wC90Nex/6wN1CZew+TzuZDLMN+DfIcQ2Zgy2ExR4ejT669VmxMvLz4Bcpk -9Ok0oSy1c+HCPujIyTQlCFzz7abHlJ+tiEMl1+E5YP6sOVkCAwEAAaNCMEAwDgYDVR0PAQH/BAQD -AgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJ/uRLOU1fqRTy7ZVZoEVtstxNulMA0GCSqG -SIb3DQEBBQUAA4IBAQB/X7lTW2M9dTLn+sR0GstG30ZpHFLPqk/CaOv/gKlR6D1id4k9CnU58W5d -F4dvaAXBlGzZXd/aslnLpRCKysw5zZ/rTt5S/wzw9JKp8mxTq5vSR6AfdPebmvEvFZ96ZDAYBzwq -D2fK/A+JYZ1lpTzlvBNbCNvj/+27BrtqBrF6T2XGgv0enIu1De5Iu7i9qgi0+6N8y5/NkHZchpZ4 -Vwpm+Vganf2XKWDeEaaQHBkc7gGWIjQ0LpH5t8Qn0Xvmv/uARFoW5evg1Ao4vOSR49XrXMGs3xtq -fJ7lddK2l4fbzIcrQzqECK+rPNv3PGYxhrCdU3nt+CPeQuMtgvEP5fqX ------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----- - -A-Trust-nQual-03 -================ ------BEGIN CERTIFICATE----- -MIIDzzCCAregAwIBAgIDAWweMA0GCSqGSIb3DQEBBQUAMIGNMQswCQYDVQQGEwJBVDFIMEYGA1UE -Cgw/QS1UcnVzdCBHZXMuIGYuIFNpY2hlcmhlaXRzc3lzdGVtZSBpbSBlbGVrdHIuIERhdGVudmVy -a2VociBHbWJIMRkwFwYDVQQLDBBBLVRydXN0LW5RdWFsLTAzMRkwFwYDVQQDDBBBLVRydXN0LW5R -dWFsLTAzMB4XDTA1MDgxNzIyMDAwMFoXDTE1MDgxNzIyMDAwMFowgY0xCzAJBgNVBAYTAkFUMUgw -RgYDVQQKDD9BLVRydXN0IEdlcy4gZi4gU2ljaGVyaGVpdHNzeXN0ZW1lIGltIGVsZWt0ci4gRGF0 -ZW52ZXJrZWhyIEdtYkgxGTAXBgNVBAsMEEEtVHJ1c3QtblF1YWwtMDMxGTAXBgNVBAMMEEEtVHJ1 -c3QtblF1YWwtMDMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtPWFuA/OQO8BBC4SA -zewqo51ru27CQoT3URThoKgtUaNR8t4j8DRE/5TrzAUjlUC5B3ilJfYKvUWG6Nm9wASOhURh73+n -yfrBJcyFLGM/BWBzSQXgYHiVEEvc+RFZznF/QJuKqiTfC0Li21a8StKlDJu3Qz7dg9MmEALP6iPE -SU7l0+m0iKsMrmKS1GWH2WrX9IWf5DMiJaXlyDO6w8dB3F/GaswADm0yqLaHNgBid5seHzTLkDx4 -iHQF63n1k3Flyp3HaxgtPVxO59X4PzF9j4fsCiIvI+n+u33J4PTs63zEsMMtYrWacdaxaujs2e3V -cuy+VwHOBVWf3tFgiBCzAgMBAAGjNjA0MA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0OBAoECERqlWdV -eRFPMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAVdRU0VlIXLOThaq/Yy/kgM40 -ozRiPvbY7meIMQQDbwvUB/tOdQ/TLtPAF8fGKOwGDREkDg6lXb+MshOWcdzUzg4NCmgybLlBMRmr -sQd7TZjTXLDR8KdCoLXEjq/+8T/0709GAHbrAvv5ndJAlseIOrifEXnzgGWovR/TeIGgUUw3tKZd -JXDRZslo+S4RFGjxVJgIrCaSD96JntT6s3kr0qN51OyLrIdTaEJMUVF0HhsnLuP1Hyl0Te2v9+GS -mYHovjrHF1D2t8b8m7CKa9aIA5GPBnc6hQLdmNVDeD/GMBWsm2vLV7eJUYs66MmEDNuxUCAKGkq6 -ahq97BvIxYSazQ== ------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----- diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/functions.php b/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/functions.php deleted file mode 100644 index 9dcce36e3e437f06e2fd9ea0c53147bfe253b50b..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/GuzzleHttp/functions.php +++ /dev/null @@ -1,325 +0,0 @@ -send($client->createRequest($method, $url, $options)); -} - -/** - * Send a GET request - * - * @param string $url URL of the request - * @param array $options Array of request options - * - * @return ResponseInterface - */ -function get($url, array $options = []) -{ - return request('GET', $url, $options); -} - -/** - * Send a HEAD request - * - * @param string $url URL of the request - * @param array $options Array of request options - * - * @return ResponseInterface - */ -function head($url, array $options = []) -{ - return request('HEAD', $url, $options); -} - -/** - * Send a DELETE request - * - * @param string $url URL of the request - * @param array $options Array of request options - * - * @return ResponseInterface - */ -function delete($url, array $options = []) -{ - return request('DELETE', $url, $options); -} - -/** - * Send a POST request - * - * @param string $url URL of the request - * @param array $options Array of request options - * - * @return ResponseInterface - */ -function post($url, array $options = []) -{ - return request('POST', $url, $options); -} - -/** - * Send a PUT request - * - * @param string $url URL of the request - * @param array $options Array of request options - * - * @return ResponseInterface - */ -function put($url, array $options = []) -{ - return request('PUT', $url, $options); -} - -/** - * Send a PATCH request - * - * @param string $url URL of the request - * @param array $options Array of request options - * - * @return ResponseInterface - */ -function patch($url, array $options = []) -{ - return request('PATCH', $url, $options); -} - -/** - * Send an OPTIONS request - * - * @param string $url URL of the request - * @param array $options Array of request options - * - * @return ResponseInterface - */ -function options($url, array $options = []) -{ - return request('OPTIONS', $url, $options); -} - -/** - * Convenience method for sending multiple requests in parallel and retrieving - * a hash map of requests to response objects or RequestException objects. - * - * Note: This method keeps every request and response in memory, and as such is - * NOT recommended when sending a large number or an indeterminable number of - * requests in parallel. - * - * @param ClientInterface $client Client used to send the requests - * @param array|\Iterator $requests Requests to send in parallel - * @param array $options Passes through the options available in - * {@see GuzzleHttp\ClientInterface::sendAll()} - * @return \SplObjectStorage Requests are the key and each value is a - * {@see GuzzleHttp\Message\ResponseInterface} if the request succeeded or - * a {@see GuzzleHttp\Exception\RequestException} if it failed. - * @throws \InvalidArgumentException if the event format is incorrect. - */ -function batch(ClientInterface $client, $requests, array $options = []) -{ - $hash = new \SplObjectStorage(); - foreach ($requests as $request) { - $hash->attach($request); - } - - // Merge the necessary complete and error events to the event listeners so - // that as each request succeeds or fails, it is added to the result hash. - $options = RequestEvents::convertEventArray( - $options, - ['complete', 'error'], - [ - 'priority' => RequestEvents::EARLY, - 'once' => true, - 'fn' => function ($e) use ($hash) { $hash[$e->getRequest()] = $e; } - ] - ); - - // Send the requests in parallel and aggregate the results. - $client->sendAll($requests, $options); - - // Update the received value for any of the intercepted requests. - foreach ($hash as $request) { - if ($hash[$request] instanceof CompleteEvent) { - $hash[$request] = $hash[$request]->getResponse(); - } elseif ($hash[$request] instanceof ErrorEvent) { - $hash[$request] = $hash[$request]->getException(); - } - } - - return $hash; -} - -/** - * Gets a value from an array using a path syntax to retrieve nested data. - * - * This method does not allow for keys that contain "/". You must traverse - * the array manually or using something more advanced like JMESPath to - * work with keys that contain "/". - * - * // Get the bar key of a set of nested arrays. - * // This is equivalent to $collection['foo']['baz']['bar'] but won't - * // throw warnings for missing keys. - * GuzzleHttp\get_path($data, 'foo/baz/bar'); - * - * @param array $data Data to retrieve values from - * @param string $path Path to traverse and retrieve a value from - * - * @return mixed|null - */ -function get_path($data, $path) -{ - $path = explode('/', $path); - - while (null !== ($part = array_shift($path))) { - if (!is_array($data) || !isset($data[$part])) { - return null; - } - $data = $data[$part]; - } - - return $data; -} - -/** - * Set a value in a nested array key. Keys will be created as needed to set the - * value. - * - * This function does not support keys that contain "/" or "[]" characters - * because these are special tokens used when traversing the data structure. - * A value may be prepended to an existing array by using "[]" as the final - * key of a path. - * - * GuzzleHttp\get_path($data, 'foo/baz'); // null - * GuzzleHttp\set_path($data, 'foo/baz/[]', 'a'); - * GuzzleHttp\set_path($data, 'foo/baz/[]', 'b'); - * GuzzleHttp\get_path($data, 'foo/baz'); - * // Returns ['a', 'b'] - * - * @param array $data Data to modify by reference - * @param string $path Path to set - * @param mixed $value Value to set at the key - * @throws \RuntimeException when trying to setPath using a nested path that - * travels through a scalar value. - */ -function set_path(&$data, $path, $value) -{ - $current =& $data; - $queue = explode('/', $path); - while (null !== ($key = array_shift($queue))) { - if (!is_array($current)) { - throw new \RuntimeException("Trying to setPath {$path}, but " - . "{$key} is set and is not an array"); - } elseif (!$queue) { - if ($key == '[]') { - $current[] = $value; - } else { - $current[$key] = $value; - } - } elseif (isset($current[$key])) { - $current =& $current[$key]; - } else { - $current[$key] = []; - $current =& $current[$key]; - } - } -} - -/** - * Expands a URI template - * - * @param string $template URI template - * @param array $variables Template variables - * - * @return string - */ -function uri_template($template, array $variables) -{ - if (function_exists('\\uri_template')) { - return \uri_template($template, $variables); - } - - static $uriTemplate; - if (!$uriTemplate) { - $uriTemplate = new UriTemplate(); - } - - return $uriTemplate->expand($template, $variables); -} - -/** - * Wrapper for JSON decode that implements error detection with helpful error - * messages. - * - * @param string $json JSON data to parse - * @param bool $assoc When true, returned objects will be converted into - * associative arrays. - * @param int $depth User specified recursion depth. - * @param int $options Bitmask of JSON decode options. - * - * @return mixed - * @throws \InvalidArgumentException if the JSON cannot be parsed. - * @link http://www.php.net/manual/en/function.json-decode.php - */ -function json_decode($json, $assoc = false, $depth = 512, $options = 0) -{ - static $jsonErrors = [ - JSON_ERROR_DEPTH => 'JSON_ERROR_DEPTH - Maximum stack depth exceeded', - JSON_ERROR_STATE_MISMATCH => 'JSON_ERROR_STATE_MISMATCH - Underflow or the modes mismatch', - JSON_ERROR_CTRL_CHAR => 'JSON_ERROR_CTRL_CHAR - Unexpected control character found', - JSON_ERROR_SYNTAX => 'JSON_ERROR_SYNTAX - Syntax error, malformed JSON', - JSON_ERROR_UTF8 => 'JSON_ERROR_UTF8 - Malformed UTF-8 characters, possibly incorrectly encoded' - ]; - - $data = \json_decode($json, $assoc, $depth, $options); - - if (JSON_ERROR_NONE !== json_last_error()) { - $last = json_last_error(); - throw new \InvalidArgumentException( - 'Unable to parse JSON data: ' - . (isset($jsonErrors[$last]) ? $jsonErrors[$last] : 'Unknown error') - ); - } - - return $data; -} - -/** - * @internal - */ -function deprecation_proxy($object, $name, $arguments, $map) -{ - if (!isset($map[$name])) { - throw new \BadMethodCallException('Unknown method, ' . $name); - } - - $message = sprintf('%s is deprecated and will be removed in a future ' - . 'version. Update your code to use the equivalent %s method ' - . 'instead to avoid breaking changes when this shim is removed.', - get_class($object) . '::' . $name . '()', - get_class($object) . '::' . $map[$name] . '()' - ); - - trigger_error($message, E_USER_DEPRECATED); - - return call_user_func_array([$object, $map[$name]], $arguments); -} diff --git a/rainloop/app/rainloop/v/1.12.0/static/js/min/admin.min.js b/rainloop/app/rainloop/v/1.12.0/static/js/min/admin.min.js deleted file mode 100644 index 28731497b637b870b9312d56343fd21af0b05009..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/static/js/min/admin.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e){function t(i){if(n[i])return n[i].exports;var o=n[i]={i:i,l:!1,exports:{}};return e[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var n={};t.m=e,t.c=n,t.d=function(e,n,i){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:i})},t.r=function(e){Object.defineProperty(e,"__esModule",{value:!0})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="rainloop/v/0.0.0/static/js/min/",t(t.s=191)}([function(e,t,n){"use strict";n.r(t),n.d(t,"FileType",function(){return i}),n.d(t,"StorageResultType",function(){return o}),n.d(t,"Focused",function(){return a}),n.d(t,"State",function(){return r}),n.d(t,"StateType",function(){return s}),n.d(t,"Capa",function(){return c}),n.d(t,"KeyState",function(){return l}),n.d(t,"FolderType",function(){return u}),n.d(t,"ServerFolderType",function(){return d}),n.d(t,"LoginSignMeTypeAsString",function(){return p}),n.d(t,"LoginSignMeType",function(){return f}),n.d(t,"ComposeType",function(){return m}),n.d(t,"UploadErrorCode",function(){return h}),n.d(t,"SetSystemFoldersNotification",function(){return g}),n.d(t,"ClientSideKeyName",function(){return b}),n.d(t,"EventKeyCode",function(){return v}),n.d(t,"MessageSetAction",function(){return S}),n.d(t,"MessageSelectAction",function(){return y}),n.d(t,"DesktopNotification",function(){return w}),n.d(t,"MessagePriority",function(){return A}),n.d(t,"EditorDefaultType",function(){return O}),n.d(t,"ServerSecure",function(){return T}),n.d(t,"SearchDateType",function(){return C}),n.d(t,"SaveSettingsStep",function(){return _}),n.d(t,"Layout",function(){return E}),n.d(t,"FilterConditionField",function(){return D}),n.d(t,"FilterConditionType",function(){return N}),n.d(t,"FiltersAction",function(){return j}),n.d(t,"FilterRulesType",function(){return R}),n.d(t,"SignedVerifyStatus",function(){return I}),n.d(t,"ContactPropertyType",function(){return x}),n.d(t,"Magics",function(){return P}),n.d(t,"Ports",function(){return k}),n.d(t,"Notification",function(){return L});var i={Unknown:"unknown",Text:"text",Html:"html",Code:"code",Eml:"eml",WordText:"word-text",Pdf:"pdf",Image:"image",Audio:"audio",Video:"video",Sheet:"sheet",Presentation:"presentation",Certificate:"certificate",CertificateBin:"certificate-bin",Archive:"archive"},o={Success:"success",Abort:"abort",Error:"error",Unload:"unload"},a={None:"none",MessageList:"message-list",MessageView:"message-view",FolderList:"folder-list"},r={Empty:10,Login:20,Auth:30},s={Webmail:0,Admin:1},c={TwoFactor:"TWO_FACTOR",TwoFactorForce:"TWO_FACTOR_FORCE",OpenPGP:"OPEN_PGP",Prefetch:"PREFETCH",Gravatar:"GRAVATAR",Folders:"FOLDERS",Composer:"COMPOSER",Contacts:"CONTACTS",Reload:"RELOAD",Search:"SEARCH",SearchAdv:"SEARCH_ADV",MessageActions:"MESSAGE_ACTIONS",MessageListActions:"MESSAGELIST_ACTIONS",AttachmentsActions:"ATTACHMENTS_ACTIONS",DangerousActions:"DANGEROUS_ACTIONS",Settings:"SETTINGS",Help:"HELP",Themes:"THEMES",UserBackground:"USER_BACKGROUND",Sieve:"SIEVE",Filters:"FILTERS",AttachmentThumbnails:"ATTACHMENT_THUMBNAILS",Templates:"TEMPLATES",AutoLogout:"AUTOLOGOUT",AdditionalAccounts:"ADDITIONAL_ACCOUNTS",Identities:"IDENTITIES"},l={All:"all",None:"none",ContactList:"contact-list",MessageList:"message-list",FolderList:"folder-list",MessageView:"message-view",Compose:"compose",Settings:"settings",Menu:"menu",PopupComposeOpenPGP:"compose-open-pgp",PopupMessageOpenPGP:"message-open-pgp",PopupViewOpenPGP:"view-open-pgp",PopupKeyboardShortcutsHelp:"popup-keyboard-shortcuts-help",PopupAsk:"popup-ask"},u={Inbox:10,SentItems:11,Draft:12,Trash:13,Spam:14,Archive:15,NotSpam:80,User:99},d={USER:0,INBOX:1,SENT:2,DRAFTS:3,JUNK:4,TRASH:5,IMPORTANT:10,FLAGGED:11,ALL:12},p={DefaultOff:"defaultoff",DefaultOn:"defaulton",Unused:"unused"},f={DefaultOff:0,DefaultOn:1,Unused:2},m={Empty:"empty",Reply:"reply",ReplyAll:"replyall",Forward:"forward",ForwardAsAttachment:"forward-as-attachment",Draft:"draft",EditAsNew:"editasnew"},h={Normal:0,FileIsTooBig:1,FilePartiallyUploaded:2,FileNoUploaded:3,MissingTempFolder:4,FileOnSaveingError:5,FileType:98,Unknown:99},g={None:0,Sent:1,Draft:2,Spam:3,Trash:4,Archive:5},b={FoldersLashHash:0,MessagesInboxLastHash:1,MailBoxListSize:2,ExpandedFolders:3,FolderListSize:4,MessageListSize:5,LastReplyAction:6,LastSignMe:7,ComposeLastIdentityID:8,MessageHeaderFullInfo:9,MessageAttachmnetControls:10},v={Backspace:8,Tab:9,Enter:13,Esc:27,PageUp:33,PageDown:34,Left:37,Right:39,Up:38,Down:40,End:35,Home:36,Space:32,Insert:45,Delete:46,A:65,S:83},S={SetSeen:0,UnsetSeen:1,SetFlag:2,UnsetFlag:3},y={All:0,None:1,Invert:2,Unseen:3,Seen:4,Flagged:5,Unflagged:6},w={Allowed:0,NotAllowed:1,Denied:2,NotSupported:9},A={Low:5,Normal:3,High:1},O={Html:"Html",Plain:"Plain",HtmlForced:"HtmlForced",PlainForced:"PlainForced"},T={None:0,SSL:1,TLS:2},C={All:-1,Days3:3,Days7:7,Month:30},_={Animate:-2,Idle:-1,TrueResult:1,FalseResult:0},E={NoPreview:0,SidePreview:1,BottomPreview:2},D={From:"From",Recipient:"Recipient",Subject:"Subject",Header:"Header",Size:"Size"},N={Contains:"Contains",NotContains:"NotContains",EqualTo:"EqualTo",NotEqualTo:"NotEqualTo",Regex:"Regex",Over:"Over",Under:"Under"},j={None:"None",MoveTo:"MoveTo",Discard:"Discard",Vacation:"Vacation",Reject:"Reject",Forward:"Forward"},R={All:"All",Any:"Any"},I={UnknownPublicKeys:-4,UnknownPrivateKey:-3,Unverified:-2,Error:-1,None:0,Success:1},x={Unknown:0,FullName:10,FirstName:15,LastName:16,MiddleName:16,Nick:18,NamePrefix:20,NameSuffix:21,Email:30,Phone:31,Web:32,Birthday:40,Facebook:90,Skype:91,GitHub:92,Note:110,Custom:250},P={EventWhichMouseMiddle:3,ifvisibleIdle10s:10,BitLength2048:2048,BitLength1024:1024,Size350px:350,Size50px:50,Size20px:20,Size1px:1,Time30mInMin:30,Time60m:36e5,Time30m:18e5,Time20m:12e5,Time15m:9e5,Time10m:6e5,Time5m:3e5,Time3m:18e4,Time2m:12e4,Time1m:6e4,Time30s:3e4,Time10s:1e4,Time7s:7e3,Time5s:5e3,Time3s:3e3,Time1s:1e3,Time500ms:500,Time350ms:350,Time250ms:250,Time200ms:200,Time100ms:100,Time50ms:50,Time20ms:20,Time10ms:10,Time1ms:1},k={Imap:143,ImapSsl:993,Smtp:25,SmtpSsl:465,SmtpStartTls:587},L={InvalidToken:101,AuthError:102,AccessError:103,ConnectionError:104,CaptchaError:105,SocialFacebookLoginAccessDisable:106,SocialTwitterLoginAccessDisable:107,SocialGoogleLoginAccessDisable:108,DomainNotAllowed:109,AccountNotAllowed:110,AccountTwoFactorAuthRequired:120,AccountTwoFactorAuthError:121,CouldNotSaveNewPassword:130,CurrentPasswordIncorrect:131,NewPasswordShort:132,NewPasswordWeak:133,NewPasswordForbidden:134,ContactsSyncError:140,CantGetMessageList:201,CantGetMessage:202,CantDeleteMessage:203,CantMoveMessage:204,CantCopyMessage:205,CantSaveMessage:301,CantSendMessage:302,InvalidRecipients:303,CantSaveFilters:351,CantGetFilters:352,FiltersAreNotCorrect:355,CantCreateFolder:400,CantRenameFolder:401,CantDeleteFolder:402,CantSubscribeFolder:403,CantUnsubscribeFolder:404,CantDeleteNonEmptyFolder:405,CantSaveSettings:501,CantSavePluginSettings:502,DomainAlreadyExists:601,CantInstallPackage:701,CantDeletePackage:702,InvalidPluginPackage:703,UnsupportedPluginPackage:704,LicensingServerIsUnavailable:710,LicensingExpired:711,LicensingBanned:712,DemoSendMessageError:750,DemoAccountError:751,AccountAlreadyExists:801,AccountDoesNotExist:802,MailServerError:901,ClientViewError:902,InvalidInputArgument:903,AjaxFalse:950,AjaxAbort:951,AjaxParse:952,AjaxTimeout:953,UnknownNotification:999,UnknownError:999}},function(e,t,n){"use strict";var i=n(3),o=n.n(i),a=n(4),r=n.n(a),s=n(7),c=n.n(s),l=o.a.Opentip||{};l.styles=l.styles||{},l.styles.rainloop={extends:"standard",fixed:!0,target:!0,delay:.2,hideDelay:0,hideEffect:"fade",hideEffectDuration:.2,showEffect:"fade",showEffectDuration:.2,showOn:"mouseover click",removeElementsOnHide:!0,background:"#fff",shadow:!1,borderColor:"#999",borderRadius:2,borderWidth:1},l.styles.rainloopTip={extends:"rainloop",delay:.4,group:"rainloopTips"},l.styles.rainloopErrorTip={extends:"rainloop",className:"rainloopErrorTip"};var u=n(97),d=n.n(u),p=n(0),f=o.a.ko,m=c()(o.a);f.bindingHandlers.updateWidth={init:function(e,t){var n=c()(e),i=t(),a=function(){i(n.width()),o.a.setTimeout(function(){i(n.width())},p.Magics.Time500ms)};m.on("resize",a),a(),f.utils.domNodeDisposal.addDisposeCallback(e,function(){m.off("resize",a)})}},f.bindingHandlers.editor={init:function(e,t){var i=null,o=t(),a=n(95).default,r=function(){o&&o.__editor&&o.__editor.setHtmlOrPlain(o())},s=function(){o&&o.__editor&&o(o.__editor.getDataWithHtmlMark())};f.isObservable(o)&&a&&(i=new a(e,s,function(){o.__editor=i,r()},s),o.__fetchEditorValue=s,o.subscribe(r))}},f.bindingHandlers.json={init:function(e,t){c()(e).text(o.a.JSON.stringify(f.unwrap(t())))},update:function(e,t){c()(e).text(o.a.JSON.stringify(f.unwrap(t())))}},f.bindingHandlers.scrollerShadows={init:function(e){var t=c()(e),n=t.find("[data-scroller-shadows-content]")[0]||null,i=r.a.throttle(function(){t.toggleClass("scroller-shadow-top",8=n.left&&e.pageX<=n.left+t.width()){if(e.pageY>=i-100&&e.pageY<=i){var a=function(){t.scrollTop(t.scrollTop()+3),r.windowResize()};t.data("timerScroll",o.a.setInterval(a,10)),a()}if(e.pageY>=n.top&&e.pageY<=n.top+100){var s=function(){t.scrollTop(t.scrollTop()-3),r.windowResize()};t.data("timerScroll",o.a.setInterval(s,10)),s()}}})},u.stop=function(){c()(l).each(function(){var e=c()(this);o.a.clearInterval(e.data("timerScroll")),e.data("timerScroll",!1)})}),u.helper=function(e){return t()(e&&e.target?f.dataFor(e.target):null)},c()(e).draggable(u).on("mousedown.koDraggable",function(){r.removeInFocus()}),f.utils.domNodeDisposal.addDisposeCallback(e,function(){c()(e).off("mousedown.koDraggable").draggable("destroy")})}}},f.bindingHandlers.droppable={init:function(e,t,i){if(!n(6).bMobileDevice){var o=t(),a=i(),r=a&&a.droppableOver?a.droppableOver:null,s=a&&a.droppableOut?a.droppableOut:null,l={tolerance:"pointer",hoverClass:"droppableHover",drop:null,over:null,out:null};o&&(l.drop=function(e,t){o(e,t)},r&&(l.over=function(e,t){r(e,t)}),s&&(l.out=function(e,t){s(e,t)}),c()(e).droppable(l),f.utils.domNodeDisposal.addDisposeCallback(e,function(){c()(e).droppable("destroy")}))}}},f.bindingHandlers.nano={init:function(e){var t=n(6),i=n(5);t.bDisableNanoScroll||i.appSettingsGet("useNativeScrollbars")||c()(e).addClass("nano").nanoScroller({iOSNativeScrolling:!1,preventPageScrolling:!0})}},f.bindingHandlers.saveTrigger={init:function(e){var t=c()(e);t.data("save-trigger-type",t.is("input[type=text],input[type=email],input[type=password],select,textarea")?"input":"custom"),"custom"===t.data("save-trigger-type")?t.append('  ').addClass("settings-saved-trigger"):t.addClass("settings-saved-trigger-input")},update:function(e,t){var n=f.unwrap(t()),i=c()(e);if("custom"===i.data("save-trigger-type"))switch(n.toString()){case"1":i.find(".animated,.error").hide().removeClass("visible").end().find(".success").show().addClass("visible");break;case"0":i.find(".animated,.success").hide().removeClass("visible").end().find(".error").show().addClass("visible");break;case"-2":i.find(".error,.success").hide().removeClass("visible").end().find(".animated").show().addClass("visible");break;default:i.find(".animated").hide().end().find(".error,.success").removeClass("visible")}else switch(n.toString()){case"1":i.addClass("success").removeClass("error");break;case"0":i.addClass("error").removeClass("success");break;case"-2":break;default:i.removeClass("error success")}}},f.bindingHandlers.emailsTags={init:function(e,t,i){var o=n(2),a=n(44).default,s=c()(e),l=t(),u=i().autoCompleteSource||null,d=[",",";","\n"];s.inputosaurus({parseOnBlur:!0,allowDragAndDrop:!0,focusCallback:function(e){l&&l.focused&&l.focused(!!e)},inputDelimiters:d,autoCompleteSource:u,splitHook:function(e){var t=o.trim(e);return t&&-1=o&&(o=t),o===e()&&""+o!=""+n&&e(o+1),e(o)}});return o(e()),o},f.extenders.limitedList=function(e,t){var i=n(2),o=f.computed({read:e,write:function(n){var o=f.unwrap(e),a=f.unwrap(t);i.isNonEmptyArray(a)?-11&&void 0!==arguments[1])||arguments[1];return!!o(e)&&(t?/^[0-9]*$/.test(e.toString()):/^[1-9]+[0-9]*$/.test(e.toString()))}function r(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=o(e)&&""!==e?ce.a.parseInt(e,10):t;return ce.a.isNaN(n)?t:n}function s(e){return o(e)?""+e:""}function c(e){return!!e}function l(e){return e?"1":"0"}function u(e){return Oe(e)&&00&&void 0!==arguments[0]?arguments[0]:32,t="0123456789abcdefghijklmnopqrstuvwxyz",n=t.length;e=r(e);for(var i="";i.length1&&void 0!==arguments[1]?arguments[1]:100,n="",i="",o=e,a=0,r=0;o.length>t;)a=(i=o.substring(0,t)).lastIndexOf(" "),-1!==(r=i.lastIndexOf("\n"))&&(a=r),-1===a&&(a=t),n+=i.substring(0,a)+"\n",o=o.substring(a+1);return n+o}function S(){try{if(ce.a.document.activeElement)return _e(ce.a.document.activeElement.__inFocusCache)&&(ce.a.document.activeElement.__inFocusCache=ue()(ce.a.document.activeElement).is("input,textarea,iframe,.cke_editable")),!!ce.a.document.activeElement.__inFocusCache}catch(e){}return!1}function y(e){if(ce.a.document&&ce.a.document.activeElement&&ce.a.document.activeElement.blur)try{var t=ue()(ce.a.document.activeElement);t&&t.is("input,textarea")?ce.a.document.activeElement.blur():e&&ce.a.document.activeElement.blur()}catch(e){}}function w(){try{if(ce.a&&ce.a.getSelection){var e=ce.a.getSelection();e&&e.removeAllRanges&&e.removeAllRanges()}else ce.a.document&&ce.a.document.selection&&ce.a.document.selection.empty&&ce.a.document.selection.empty()}catch(e){}}function A(e,t){e=we(e.toUpperCase()),t=we(t.replace(/[\s]+/g," "));var n=!1,i="RE"===e,o="FWD"===e,a=[],r=!o;return""!==t&&pe.a.each(t.split(":"),function(e){var t=we(e);n||!/^(RE|FWD)$/i.test(t)&&!/^(RE|FWD)[\[\(][\d]+[\]\)]$/i.test(t)?(a.push(e),n=!0):(i||(i=!!/^RE/i.test(t)),o||(o=!!/^FWD/i.test(t)))}),r?i=!1:o=!1,we((r?"Re: ":"Fwd: ")+(i?"Re: ":"")+(o?"Fwd: ":"")+we(a.join(":")))}function O(e,t){return ce.a.Math.round(e*ce.a.Math.pow(10,t))/ce.a.Math.pow(10,t)}function T(e){switch(e=r(e),!0){case 1073741824<=e:return O(e/1073741824,1)+"GB";case 1048576<=e:return O(e/1048576,1)+"MB";case 1024<=e:return O(e/1024,0)+"KB"}return e+"B"}function C(e){ce.a.console&&ce.a.console.log&&ce.a.console.log(e)}function _(e,t,n){var i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:0;e&&e[t]&&(i=r(i),n=Oe(n)?n:[],0>=i?e[t].apply(e,n):pe.a.delay(function(){e[t].apply(e,n)},i))}function E(e){if((e=e||ce.a.event)&&e.ctrlKey&&!e.shiftKey&&!e.altKey){var t=e.keyCode||e.which;if(t===be.EventKeyCode.S)return void e.preventDefault();if(t===be.EventKeyCode.A){var n=e.target||e.srcElement;if(n&&("true"==""+n.contentEditable||n.tagName&&n.tagName.match(/INPUT|TEXTAREA/i)))return;ce.a.getSelection?ce.a.getSelection().removeAllRanges():ce.a.document.selection&&ce.a.document.selection.clear&&ce.a.document.selection.clear(),e.preventDefault()}}}function D(e,t){var n=!(arguments.length>2&&void 0!==arguments[2])||arguments[2],i=null;return(i=t?function(){for(var n=arguments.length,o=Array(n),a=0;a1&&void 0!==arguments[1]&&arguments[1];return n(10).i18n("LANGS_NAMES"+(!0===t?"_EN":"")+"/LANG_"+e.toUpperCase().replace(/[^a-zA-Z0-9]+/g,"_"),null,e)}function x(){return ue()('
 
').appendTo("#rl-hidden")}function P(e,t){t&&!_e(t.disabled)&&e&&ue()(e).toggleClass("disabled",t.disabled).prop("disabled",t.disabled)}function k(e){e.find("blockquote.rl-bq-switcher").removeClass("rl-bq-switcher hidden-bq"),e.find(".rlBlockquoteSwitcher").off(".rlBlockquoteSwitcher").remove(),e.find("[data-html-editor-font-wrapper]").removeAttr("data-html-editor-font-wrapper")}function L(e,t,i,o){var a=e.title,r=e.subject,s=e.date,c=e.fromCreds,l=e.toCreds,u=e.toLabel,d=e.ccClass,p=e.ccCreds,f=e.ccLabel,m=ce.a.open(""),h=m.document,g=t.clone(),v=i?"html":"plain";k(g);var S=g?g.html():"";h.write(n(170).replace("{{title}}",b(a)).replace("{{subject}}",b(r)).replace("{{date}}",b(s)).replace("{{fromCreds}}",b(c)).replace("{{toCreds}}",b(l)).replace("{{toLabel}}",b(u)).replace("{{ccClass}}",b(d)).replace("{{ccCreds}}",b(p)).replace("{{ccLabel}}",b(f)).replace("{{bodyClass}}",v).replace("{{html}}",S)),h.close(),o&&ce.a.setTimeout(function(){return m.print()},100)}function M(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:1e3;return i=r(i),function(o,a,r,s,c){t.call(n,a&&a.Result?be.SaveSettingsStep.TrueResult:be.SaveSettingsStep.FalseResult),e&&e.call(n,o,a,r,s,c),pe.a.delay(function(){t.call(n,be.SaveSettingsStep.Idle)},i)}}function F(e,t){return M(null,e,t,1e3)}function U(e,t,n,i){return function(o){if(e){switch(n){case"bool":case"boolean":o=o?"1":"0";break;case"int":case"integer":case"number":o=r(o);break;case"trim":o=we(o);break;default:o=s(o)}var a={};a[t]=o,e.saveAdminConfig?e.saveAdminConfig(i||null,a):e.saveSettings&&e.saveSettings(i||null,a)}}}function H(e){return he.a?he.a.link(e,{newWindow:!0,stripPrefix:!1,urls:!0,email:!0,mention:!1,phone:!1,hashtag:!1,replaceFn:function(e){return!(e&&"url"===e.getType()&&e.matchedText&&0!==e.matchedText.indexOf("http"))}}):e}function G(e){var t,n=0,i=0,o=0,a=0,r=0,s="";for(s=e.replace(/]*><\/p>/gi,"").replace(/]*>([\s\S\r\n\t]*)<\/pre>/gim,function(){for(var e=arguments.length,t=Array(e),n=0;n").replace(/[\r]/gm,""):""}).replace(/[\s]+/gm," ").replace(/((?:href|data)\s?=\s?)("[^"]+?"|'[^']+?')/gim,function(){for(var e=arguments.length,t=Array(e),n=0;n]*>/gim,"\n").replace(/<\/h[\d]>/gi,"\n").replace(/<\/p>/gi,"\n\n").replace(/]*>/gim,"\n").replace(/<\/ul>/gi,"\n").replace(/]*>/gim," * ").replace(/<\/li>/gi,"\n").replace(/<\/td>/gi,"\n").replace(/<\/tr>/gi,"\n").replace(/]*>/gim,"\n_______________________________\n\n").replace(/]*>([\s\S\r\n]*)<\/div>/gim,function e(){for(var t=arguments.length,n=Array(t),i=0;i]*>([\s\S\r\n]*)<\/div>/gim,e),o="\n"+we(o)+"\n"),o}return""}).replace(/]*>/gim,"\n__bq__start__\n").replace(/<\/blockquote>/gim,"\n__bq__end__\n").replace(/]*>([\s\S\r\n]*?)<\/a>/gim,function(){for(var e=arguments.length,t=Array(e),n=0;n/gi,"\n").replace(/ /gi," ").replace(/"/gi,'"').replace(/<[^>]*>/gm,""),s=v(s=(s=ge.$div.html(s).text()).replace(/\n[ \t]+/gm,"\n").replace(/[\n]{3,}/gm,"\n\n").replace(/>/gi,">").replace(/</gi,"<").replace(/&/gi,"&")),n=0,i=800;0 "+we(t).replace(/\n/gm,"\n> ")).replace(/(^|\n)([> ]+)/gm,function(){for(var e=arguments.length,t=Array(e),n=0;n1&&void 0!==arguments[1]&&arguments[1],n=!1,i=!0,o=!0,a=[],r="",s=0,c=(e=(e=e.toString().replace(/\r/g,"")).replace(/^>[> ]>+/gm,function(e){var t=e[0];return t?t.replace(/[ ]+/g,""):t})).split("\n");do{for(i=!1,a=[],s=0;s"===(r=c[s]).substr(0,1))&&!n?(i=!0,n=!0,a.push("~~~blockquote~~~"),a.push(r.substr(1))):!o&&n?""!==r?(n=!1,a.push("~~~/blockquote~~~"),a.push(r)):a.push(r):o&&n?a.push(r.substr(1)):a.push(r);n&&(n=!1,a.push("~~~/blockquote~~~")),c=a}while(i);return e=(e=c.join("\n")).replace(/&/g,"&").replace(/>/g,">").replace(/").replace(/[\s]*~~~\/blockquote~~~/g,"").replace(/\n/g,"
"),t?H(e):e}function V(e,t,n,i,a,r,s,c,l,u){var d=null,p=!1,f=0,m=0,h=[];for(u=!_e(u)&&!!u,l=o(l)?l:00&&void 0!==arguments[0]&&arguments[0]?pe.a.delay(e,100):e()}function K(e){Me[e]||(Me[e]=ue()('script[type="application/json"][data-configuration="'+e+'"]'));try{return JSON.parse(Me[e].text())}catch(e){}return{}}function W(e,t){var n=t||e;n&&"function"==typeof n.dispose&&n.dispose()}function Y(e){e&&(Oe(e.disposables)&&pe.a.each(e.disposables,W),fe.a.utils.objectForEach(e,W))}function $(e){e&&(Oe(e)?pe.a.each(e,function(e){$(e)}):e&&e.onDestroy&&e.onDestroy())}function J(e,t){return!(!e||!e[0]||(e[0].styleSheet&&!_e(e[0].styleSheet.cssText)?e[0].styleSheet.cssText=t:e.text(t),0))}function X(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:je,n=ue()("#app-theme-link"),i=function(){Fe=ce.a.setTimeout(function(){return t(be.SaveSettingsStep.Idle)},1e3),Ue=null},o=ue()("#app-theme-style"),a=n.attr("href");a||(a=o.attr("data-href")),a&&("Json/"!==(a=(a=(a=a.toString().replace(/\/-\/[^\/]+\/\-\//,"/-/"+e+"/-/")).replace(/\/Css\/[^\/]+\/User\//,"/Css/0/User/")).replace(/\/Hash\/[^\/]+\//,"/Hash/-/")).substring(a.length-5,a.length)&&(a+="Json/"),ce.a.clearTimeout(Fe),t(be.SaveSettingsStep.Animate),Ue&&Ue.abort&&Ue.abort(),Ue=ue.a.ajax({url:a,dataType:"json"}).then(function(e){e&&Oe(e)&&2===e.length&&(!n||!n[0]||o&&o[0]||(o=ue()(''),n.after(o),n.remove()),o&&o[0]&&J(o,e[1])&&o.attr("data-href",a).attr("data-theme",e[0]),t(be.SaveSettingsStep.TrueResult))}).then(i,i))}function Q(e,t){return function(){var n=e(),i=t(),o=[],a=function(e){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"",a={current:e===n,name:""===i?e.toString():i.toString(),custom:""!==i,title:""===i?"":e.toString(),value:e.toString()};t?o.push(a):o.unshift(a)},r=0,s=0,c=2;if(1=n||i-2<=n)&&(c+=2),a(n),r=n,s=n);0=s)a(s,!0),c-=1;else if(0>=r)break;3===r?a(2,!1):3s&&a(Math.round((i+s)/2),!0,"..."),1s&&a(i,!0)}return o}}function Z(e){var t=(e=we(e).toLowerCase()).split(".").pop();return t===e?"":t}function ee(e){var t,n="application/octet-stream";return"winmail.dat"===(e=we(e).toLowerCase())?"application/ms-tnef":((t=Z(e))&&0this.height?[this.width-this.height,0]:[0,this.height-this.width],o.fillStyle="#fff",o.fillRect(0,0,t,t),o.drawImage(this,e[0]/2,e[1]/2,this.width-e[0],this.height-e[1],0,0,t,t),n(i.toDataURL("image/jpeg"))},i.src=e}function oe(e,t){if(e&&"mailto:"===e.toString().substr(0,7).toLowerCase()){if(!t)return!0;var i,o=[],a=null,r=null,c=(e=e.toString().substr(7)).replace(/\?.+$/,""),l=e.replace(/^[^\?]*\?/,""),u=n(44).default;return i=h(l),_e(i.to)?o=u.parseEmailLine(c):(o=u.parseEmailLine(p(c+","+i.to)),o=pe.a.values(o.reduce(function(e,t){return t&&(e[t.email]&&e[t.email].name||(e[t.email]=t)),e},{}))),_e(i.cc)||(a=u.parseEmailLine(p(i.cc))),_e(i.bcc)||(r=u.parseEmailLine(p(i.bcc))),n(9).showScreenPopup(t,[be.ComposeType.Empty,null,o,a,r,_e(i.subject)?null:s(p(i.subject)),_e(i.body)?null:B(s(p(i.body)))]),!0}return!1}function ae(e){ue()(function(){return e()})}function re(){He()}n.r(t);var se=n(3),ce=n.n(se),le=n(7),ue=n.n(le),de=n(4),pe=n.n(de),fe=n(1),me=n(96),he=n.n(me),ge=n(6),be=n(0),ve={eml:"message/rfc822",mime:"message/rfc822",txt:"text/plain",text:"text/plain",def:"text/plain",list:"text/plain",in:"text/plain",ini:"text/plain",log:"text/plain",sql:"text/plain",cfg:"text/plain",conf:"text/plain",asc:"text/plain",rtx:"text/richtext",vcard:"text/vcard",vcf:"text/vcard",htm:"text/html",html:"text/html",csv:"text/csv",ics:"text/calendar",ifb:"text/calendar",xml:"text/xml",json:"application/json",swf:"application/x-shockwave-flash",hlp:"application/winhlp",wgt:"application/widget",chm:"application/vnd.ms-htmlhelp",p10:"application/pkcs10",p7c:"application/pkcs7-mime",p7m:"application/pkcs7-mime",p7s:"application/pkcs7-signature",torrent:"application/x-bittorrent",js:"application/javascript",pl:"text/perl",css:"text/css",asp:"text/asp",php:"application/x-httpd-php",php3:"application/x-httpd-php",php4:"application/x-httpd-php",php5:"application/x-httpd-php",phtml:"application/x-httpd-php",png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",jpe:"image/jpeg",jfif:"image/jpeg",gif:"image/gif",bmp:"image/bmp",cgm:"image/cgm",ief:"image/ief",ico:"image/x-icon",tif:"image/tiff",tiff:"image/tiff",svg:"image/svg+xml",svgz:"image/svg+xml",djv:"image/vnd.djvu",djvu:"image/vnd.djvu",webp:"image/webp",zip:"application/zip","7z":"application/x-7z-compressed",rar:"application/x-rar-compressed",exe:"application/x-msdownload",dll:"application/x-msdownload",scr:"application/x-msdownload",com:"application/x-msdownload",bat:"application/x-msdownload",msi:"application/x-msdownload",cab:"application/vnd.ms-cab-compressed",gz:"application/x-gzip",tgz:"application/x-gzip",bz:"application/x-bzip",bz2:"application/x-bzip2",deb:"application/x-debian-package",psf:"application/x-font-linux-psf",otf:"application/x-font-otf",pcf:"application/x-font-pcf",snf:"application/x-font-snf",ttf:"application/x-font-ttf",ttc:"application/x-font-ttf",mp3:"audio/mpeg",amr:"audio/amr",aac:"audio/x-aac",aif:"audio/x-aiff",aifc:"audio/x-aiff",aiff:"audio/x-aiff",wav:"audio/x-wav",wma:"audio/x-ms-wma",wax:"audio/x-ms-wax",midi:"audio/midi",mp4a:"audio/mp4",ogg:"audio/ogg",weba:"audio/webm",ra:"audio/x-pn-realaudio",ram:"audio/x-pn-realaudio",rmp:"audio/x-pn-realaudio-plugin",m3u:"audio/x-mpegurl",flv:"video/x-flv",qt:"video/quicktime",mov:"video/quicktime",wmv:"video/windows-media",avi:"video/x-msvideo",mpg:"video/mpeg",mpeg:"video/mpeg",mpe:"video/mpeg",m1v:"video/mpeg",m2v:"video/mpeg","3gp":"video/3gpp","3g2":"video/3gpp2",h261:"video/h261",h263:"video/h263",h264:"video/h264",jpgv:"video/jpgv",mp4:"video/mp4",mp4v:"video/mp4",mpg4:"video/mp4",ogv:"video/ogg",webm:"video/webm",m4v:"video/x-m4v",asf:"video/x-ms-asf",asx:"video/x-ms-asf",wm:"video/x-ms-wm",wmx:"video/x-ms-wmx",wvx:"video/x-ms-wvx",movie:"video/x-sgi-movie",pdf:"application/pdf",psd:"image/vnd.adobe.photoshop",ai:"application/postscript",eps:"application/postscript",ps:"application/postscript",doc:"application/msword",dot:"application/msword",rtf:"application/rtf",xls:"application/vnd.ms-excel",ppt:"application/vnd.ms-powerpoint",docx:"application/vnd.openxmlformats-officedocument.wordprocessingml.document",xlsx:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",dotx:"application/vnd.openxmlformats-officedocument.wordprocessingml.template",pptx:"application/vnd.openxmlformats-officedocument.presentationml.presentation",odt:"application/vnd.oasis.opendocument.text",ods:"application/vnd.oasis.opendocument.spreadsheet"},Se=n(59);n.d(t,"trim",function(){return we}),n.d(t,"inArray",function(){return Ae}),n.d(t,"isArray",function(){return Oe}),n.d(t,"isObject",function(){return Te}),n.d(t,"isFunc",function(){return Ce}),n.d(t,"isUnd",function(){return _e}),n.d(t,"isNull",function(){return Ee}),n.d(t,"has",function(){return De}),n.d(t,"bind",function(){return Ne}),n.d(t,"noop",function(){return je}),n.d(t,"noopTrue",function(){return Re}),n.d(t,"noopFalse",function(){return Ie}),n.d(t,"silentTryCatch",function(){return i}),n.d(t,"isNormal",function(){return o}),n.d(t,"isPosNumeric",function(){return a}),n.d(t,"pInt",function(){return r}),n.d(t,"pString",function(){return s}),n.d(t,"pBool",function(){return c}),n.d(t,"boolToAjax",function(){return l}),n.d(t,"isNonEmptyArray",function(){return u}),n.d(t,"encodeURIComponent",function(){return d}),n.d(t,"decodeURIComponent",function(){return p}),n.d(t,"decodeURI",function(){return f}),n.d(t,"encodeURI",function(){return m}),n.d(t,"simpleQueryParser",function(){return h}),n.d(t,"fakeMd5",function(){return g}),n.d(t,"encodeHtml",function(){return b}),n.d(t,"splitPlainText",function(){return v}),n.d(t,"timeOutAction",function(){return xe}),n.d(t,"timeOutActionSecond",function(){return Pe}),n.d(t,"inFocus",function(){return S}),n.d(t,"removeInFocus",function(){return y}),n.d(t,"removeSelection",function(){return w}),n.d(t,"replySubjectAdd",function(){return A}),n.d(t,"roundNumber",function(){return O}),n.d(t,"friendlySize",function(){return T}),n.d(t,"log",function(){return C}),n.d(t,"delegateRun",function(){return _}),n.d(t,"killCtrlACtrlS",function(){return E}),n.d(t,"createCommandLegacy",function(){return D}),n.d(t,"convertThemeName",function(){return ke}),n.d(t,"quoteName",function(){return N}),n.d(t,"microtime",function(){return j}),n.d(t,"timestamp",function(){return R}),n.d(t,"convertLangName",function(){return I}),n.d(t,"draggablePlace",function(){return x}),n.d(t,"defautOptionsAfterRender",function(){return P}),n.d(t,"clearBqSwitcher",function(){return k}),n.d(t,"previewMessage",function(){return L}),n.d(t,"settingsSaveHelperFunction",function(){return M}),n.d(t,"settingsSaveHelperSimpleFunction",function(){return F}),n.d(t,"settingsSaveHelperSubscribeFunction",function(){return U}),n.d(t,"findEmailAndLinks",function(){return H}),n.d(t,"htmlToPlain",function(){return G}),n.d(t,"plainToHtml",function(){return B}),n.d(t,"folderListOptionsBuilder",function(){return V}),n.d(t,"selectElement",function(){return q}),n.d(t,"detectDropdownVisibility",function(){return Le}),n.d(t,"triggerAutocompleteInputChange",function(){return z}),n.d(t,"getConfigurationFromScriptTag",function(){return K}),n.d(t,"disposeOne",function(){return W}),n.d(t,"disposeObject",function(){return Y}),n.d(t,"delegateRunOnDestroy",function(){return $}),n.d(t,"appendStyles",function(){return J}),n.d(t,"changeTheme",function(){return X}),n.d(t,"computedPagenatorHelper",function(){return Q}),n.d(t,"getFileExtension",function(){return Z}),n.d(t,"mimeContentType",function(){return ee}),n.d(t,"isTransparent",function(){return te}),n.d(t,"getRealHeight",function(){return ne}),n.d(t,"resizeAndCrop",function(){return ie}),n.d(t,"mailToHelper",function(){return oe}),n.d(t,"domReady",function(){return ae}),n.d(t,"windowResize",function(){return He}),n.d(t,"windowResizeCallback",function(){return re}),n.d(t,"jassl",function(){return Se.a});var ye,we=ue.a.trim,Ae=ue.a.inArray,Oe=pe.a.isArray,Te=pe.a.isObject,Ce=pe.a.isFunction,_e=pe.a.isUndefined,Ee=pe.a.isNull,De=pe.a.has,Ne=pe.a.bind,je=function(){},Re=function(){return!0},Ie=function(){return!1},xe=(ye={},function(e,t,n){ye[e]=_e(ye[e])?0:ye[e],ce.a.clearTimeout(ye[e]),ye[e]=ce.a.setTimeout(t,n)}),Pe=function(){var e={};return function(t,n,i){e[t]||(e[t]=ce.a.setTimeout(function(){n(),e[t]=0},i))}}(),ke=pe.a.memoize(function(e){return"@custom"===e.substr(-7)&&(e=we(e.substring(0,e.length-7))),we(e.replace(/[^a-zA-Z0-9]+/g," ").replace(/([A-Z])/g," $1").replace(/[\s]+/g," "))});ce.a.rainloop_Utils_htmlToPlain=G,ce.a.rainloop_Utils_plainToHtml=B;var Le=pe.a.debounce(function(){Object(ge.dropdownVisibility)(!!pe.a.find(ge.data.aBootstrapDropdowns,function(e){return e.hasClass("open")}))},50),Me={},Fe=0,Ue=null,He=pe.a.debounce(function(e){_e(e)||Ee(e)?ge.$win.resize():ce.a.setTimeout(function(){ge.$win.resize()},e)},50),Ge=ce.a.String.substr;"b"!=="ab".substr(-1)&&(Ge=function(e,t,n){return t=0>t?e.length+t:t,e.substr(t,n)},ce.a.String.substr=Ge)},function(e,t){e.exports=window},function(e,t){e.exports=window._},function(e,t,n){"use strict";function i(e){return Object(l.isUnd)(u[e])?null:u[e]}function o(e,t){u[e]=t}function a(e){return Object(l.isUnd)(d[e])?null:d[e]}function r(e){var t=i("Capa");return Object(l.isArray)(t)&&Object(l.isNormal)(e)&&-1"),v=c()("
");v.attr("area","hidden").css({position:"absolute",left:-5e3}).appendTo(g);var S=(new o.a.Date).getTime(),y=!0,w=d.a.observable(!1).extend({rateLimit:0}),A=d.a.observable(!0),O="navigator"in o.a&&"userAgent"in o.a.navigator&&o.a.navigator.userAgent.toLowerCase()||"",T=-11&&void 0!==arguments[1])||arguments[1];return Object(M.createCommandLegacy)(null,e,t)}function a(e,t,n,i){var o=arguments.length>4&&void 0!==arguments[4]&&arguments[4];e.__rlSettingsData={Label:n,Template:t,Route:i,IsDefault:!!o},L.VIEW_MODELS.settings.push(e)}function r(e){L.VIEW_MODELS["settings-removed"].push(e)}function s(e){L.VIEW_MODELS["settings-disabled"].push(e)}function c(){R.a.changed.active=!1}function l(){R.a.changed.active=!0}function u(e){return""===e||Object(M.isUnd)(H[e])?null:H[e]}function d(e){var t=null;return e&&(t=e,e.default&&(t=e.default)),t}function p(e){var t=d(e);t&&t.__vm&&t.__dom&&t.__vm.modalVisibility(!1)}function f(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;_.a.each(t.__names,function(i){Object(k.f)(e,[i,t.__vm,n])})}function m(e,t){if(e&&!e.__builded){var n=null,i=new e(t),a=e.__type||"",r=a?D()("#rl-content #rl-"+a.toLowerCase()):null;e.__builded=!0,e.__vm=i,i.onShowTrigger=N.a.observable(!1),i.onHideTrigger=N.a.observable(!1),i.viewModelName=e.__name,i.viewModelNames=e.__names,i.viewModelTemplateID=e.__templateID,i.viewModelPosition=e.__type,r&&1===r.length?((n=D()("
").addClass("rl-view-model").addClass("RL-"+i.viewModelTemplateID).hide()).appendTo(r),i.viewModelDom=n,e.__dom=n,G.Popup===a&&(i.cancelCommand=i.closeCommand=o(function(){p(e)}),i.modalVisibility.subscribe(function(t){t?(i.viewModelDom.show(),i.storeAndSetKeyScope(),L.popupVisibilityNames.push(i.viewModelName),i.viewModelDom.css("z-index",3e3+Object(L.popupVisibilityNames)().length+10),i.onShowTrigger&&i.onShowTrigger(!i.onShowTrigger()),Object(M.delegateRun)(i,"onShowWithDelay",[],500)):(Object(M.delegateRun)(i,"onHide"),Object(M.delegateRun)(i,"onHideWithDelay",[],500),i.onHideTrigger&&i.onHideTrigger(!i.onHideTrigger()),i.restoreKeyScope(),f("view-model-on-hide",e),L.popupVisibilityNames.remove(i.viewModelName),i.viewModelDom.css("z-index",2e3),_.a.delay(function(){return i.viewModelDom.hide()},300))})),f("view-model-pre-build",e,n),N.a.applyBindingAccessorsToNode(n[0],{translatorInit:!0,template:function(){return{name:i.viewModelTemplateID}}},i),Object(M.delegateRun)(i,"onBuild",[n]),i&&G.Popup===a&&i.registerPopupKeyDown(),f("view-model-post-build",e,n)):Object(M.log)("Cannot find view model position: "+a)}return e?e.__vm:null}function h(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],n=d(e);n&&(m(n),n.__vm&&n.__dom&&(Object(M.delegateRun)(n.__vm,"onBeforeShow",t||[]),n.__vm.modalVisibility(!0),Object(M.delegateRun)(n.__vm,"onShow",t||[]),f("view-model-on-show",n,t||[])))}function g(e){var t=d(e);t&&(m(t),t.__vm&&t.__dom&&Object(M.delegateRun)(t.__vm,"onWarmUp"))}function b(e){var t=d(e);return!(!t||!t.__vm)&&t.__vm.modalVisibility()}function v(e,t){var n=null,i=!1,o=null;""===Object(M.pString)(e)&&(e=U),""!==e&&((n=u(e))||(n=u(U))&&(t=e+"/"+t,e=U),n&&n.__started&&(i=F&&n===F,n.__builded||(n.__builded=!0,Object(M.isNonEmptyArray)(n.viewModels())&&_.a.each(n.viewModels(),function(e){m(e,n)}),Object(M.delegateRun)(n,"onBuild")),_.a.defer(function(){F&&!i&&(Object(M.delegateRun)(F,"onHide"),Object(M.delegateRun)(F,"onHideWithDelay",[],500),F.onHideTrigger&&F.onHideTrigger(!F.onHideTrigger()),Object(M.isNonEmptyArray)(F.viewModels())&&_.a.each(F.viewModels(),function(e){e.__vm&&e.__dom&&G.Popup!==e.__vm.viewModelPosition&&(e.__dom.hide(),e.__vm.viewModelVisibility(!1),Object(M.delegateRun)(e.__vm,"onHide"),Object(M.delegateRun)(e.__vm,"onHideWithDelay",[],500),e.__vm.onHideTrigger&&e.__vm.onHideTrigger(!e.__vm.onHideTrigger()))})),(F=n)&&!i&&(Object(M.delegateRun)(F,"onShow"),F.onShowTrigger&&F.onShowTrigger(!F.onShowTrigger()),Object(k.f)("screen-on-show",[F.screenName(),F]),Object(M.isNonEmptyArray)(F.viewModels())&&_.a.each(F.viewModels(),function(e){e.__vm&&e.__dom&&G.Popup!==e.__vm.viewModelPosition&&(Object(M.delegateRun)(e.__vm,"onBeforeShow"),e.__dom.show(),e.__vm.viewModelVisibility(!0),Object(M.delegateRun)(e.__vm,"onShow"),e.__vm.onShowTrigger&&e.__vm.onShowTrigger(!e.__vm.onShowTrigger()),Object(M.delegateRun)(e.__vm,"onShowWithDelay",[],200),f("view-model-on-show",e))})),(o=n&&n.__cross?n.__cross():null)&&o.parse(t)})))}function S(e){_.a.each(e,function(e){if(e){var t=new e,n=t?t.screenName():"";t&&""!==n&&(""===U&&(U=n),H[n]=t)}}),_.a.each(H,function(e){e&&!e.__started&&e.__start&&(e.__started=!0,e.__start(),Object(k.f)("screen-pre-start",[e.screenName(),e]),Object(M.delegateRun)(e,"onStart"),Object(k.f)("screen-post-start",[e.screenName(),e]))});var t=x.a.create();t.addRoute(/^([a-zA-Z0-9\-]*)\/?(.*)$/,v),R.a.initialized.add(t.parse,t),R.a.changed.add(t.parse,t),R.a.init(),_.a.delay(function(){return L.$html.removeClass("rl-started-trigger").addClass("rl-started")},100),_.a.delay(function(){return L.$html.addClass("rl-started-delay")},200)}function y(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];e="/"===(e="#"===e.substr(0,1)?e.substr(1):e).substr(0,1)?e.substr(1):e;var i=n?"replaceHash":"setHash";t?(R.a.changed.active=!1,R.a[i](e),R.a.changed.active=!0):(R.a.changed.active=!0,R.a[i](e),R.a.setHash(e))}function w(e){var t=e.name,n=e.type,i=e.templateID;return function(e){e&&(t&&(Object(M.isArray)(t)?e.__names=t:e.__names=[t],e.__name=e.__names[0]),n&&(e.__type=n),i&&(e.__templateID=i))}}function A(e){var t=e.name,n=e.templateID;return w({name:t,type:G.Popup,templateID:n})}function O(){var e=!(arguments.length>0&&void 0!==arguments[0])||arguments[0];return function(t,n,i){if(!n||!n.match(/Command$/))throw new Error('name "'+n+'" should end with Command suffix');var o=i.value||i.initializer(),a=Object(M.isFunc)(e)?e:function(){return!!e};return i.value=function(){if(a.call(this,this)){for(var e=arguments.length,t=Array(e),n=0;n1&&void 0!==arguments[1]&&arguments[1];m.a.defer(function(){g()("[data-i18n]",e).each(function(e,t){E(t)}),t&&y.bAnimationSupported&&g()(".i18n-animation[data-i18n]",e).letterfx({fx:"fall fade",backwards:!1,timing:50,fx_duration:"50ms",letter_end:"restore",element_end:"restore"})})}function a(){C.forEach(function(e){T[e[0]]=i(e[1])})}function r(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;e&&e(),t?_.subscribe(function(){e&&e(),t&&t()}):e&&_.subscribe(e)}function s(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;return e=p.a.parseInt(e,10)||0,v.Notification.ClientViewError===e&&t?t:(n=n&&p.a.parseInt(n,10)||0,Object(S.isUnd)(T[e])?n&&Object(S.isUnd)(T[n])?T[n]:"":T[e])}function c(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:v.Notification.UnknownNotification;return e&&e.ErrorCode?s(Object(S.pInt)(e.ErrorCode),e.ErrorMessage||""):s(t)}function l(e){var t="";switch(p.a.parseInt(e,10)||0){case v.UploadErrorCode.FileIsTooBig:t=i("UPLOAD/ERROR_FILE_IS_TOO_BIG");break;case v.UploadErrorCode.FilePartiallyUploaded:t=i("UPLOAD/ERROR_FILE_PARTIALLY_UPLOADED");break;case v.UploadErrorCode.FileNoUploaded:t=i("UPLOAD/ERROR_NO_FILE_UPLOADED");break;case v.UploadErrorCode.MissingTempFolder:t=i("UPLOAD/ERROR_MISSING_TEMP_FOLDER");break;case v.UploadErrorCode.FileOnSaveingError:t=i("UPLOAD/ERROR_ON_SAVING_FILE");break;case v.UploadErrorCode.FileType:t=i("UPLOAD/ERROR_FILE_TYPE");break;default:t=i("UPLOAD/ERROR_UNKNOWN")}return t}function u(e,t){var n=Object(S.microtime)();return y.$html.addClass("rl-changing-language"),new p.a.Promise(function(i,o){g.a.ajax({url:Object(A.n)(t,e),dataType:"script",cache:!0}).then(function(){m.a.delay(function(){D();var e=-10&&void 0!==arguments[0]?arguments[0]:"";return W+Object(q.pString)(e)}function r(){return ee?K:Y+te}function s(){return K}function c(e,t,n){return n=Object(q.isUnd)(n)?ne:n,Y+"/Raw/"+$+"/"+n+"/"+e+"/"+$+"/"+t}function l(e,t){return c("Download",e,t)}function u(e,t){return c("View",e,t)}function d(e,t){return c("ViewThumbnail",e,t)}function p(e,t){return c("ViewAsPlain",e,t)}function f(e,t){return c("FramedView",e,t)}function m(e){return Y+"/"+e+"/"+$+"/"+ne+"/"}function h(){return m("Upload")}function g(){return m("UploadContacts")}function b(){return m("UploadBackground")}function v(){return m("Append")}function S(e){return m("Change")+Object(q.encodeURIComponent)(e)+"/"}function y(e){return m("Ajax")+e}function w(e){return Y+"/Raw/"+$+"/"+ne+"/ViewAsPlain/"+$+"/"+e}function A(e){return Y+"/Raw/"+$+"/"+ne+"/Download/"+$+"/"+e}function O(e){return Y+"/Raw/0/Avatar/"+Object(q.encodeURIComponent)(e)+"/"}function T(e){return Y+"/Raw/"+$+"/"+ne+"/UserBackground/"+$+"/"+e}function C(){return Y+"/Info"}function _(e,t){return Y+"/Lang/0/"+(t?"Admin":"App")+"/"+V.a.encodeURI(e)+"/"+J+"/"}function E(){return Y+"/Raw/"+$+"/"+ne+"/ContactsVcf/"}function D(){return Y+"/Raw/"+$+"/"+ne+"/ContactsCsv/"}function N(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];return Y+"SocialGoogle"+(""!==ne?"/"+$+"/"+ne+"/":"")+(e?"&xauth=1":"")}function j(){return Y+"SocialTwitter"+(""!==ne?"/"+$+"/"+ne+"/":"")}function R(){return Y+"SocialFacebook"+(""!==ne?"/"+$+"/"+ne+"/":"")}function I(e){return Z+e}function x(){return I("css/images/empty-contact.png")}function P(e){return I("sounds/"+e)}function k(){return I("css/images/icom-message-notification.png")}function L(){return I("js/min/openpgp.min.js")}function M(){return I("js/min/openpgp.worker.min.js")}function F(e){var t=Q;return"@custom"===e.substr(-7)&&(e=Object(q.trim)(e.substring(0,e.length-7)),t=X),t+"themes/"+V.a.encodeURI(e)+"/images/preview.png"}function U(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"INBOX";return W+"mailbox/"+e}function H(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";return W+"settings"+(e?"/"+e:"")}function G(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"",i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"";t=Object(q.isNormal)(t)?Object(q.pInt)(t):1,n=Object(q.pString)(n);var o=W+"mailbox/";if(""!==e){var a=Object(q.pInt)(i);o+=V.a.encodeURI(e)+(01&&void 0!==arguments[1])||arguments[1];this.defaultRequest(e,"AdminDomainList",{IncludeAliases:t?"1":"0"})},t.prototype.pluginList=function(e){this.defaultRequest(e,"AdminPluginList")},t.prototype.packagesList=function(e){this.defaultRequest(e,"AdminPackagesList")},t.prototype.coreData=function(e){this.defaultRequest(e,"AdminCoreData")},t.prototype.updateCoreData=function(e){this.defaultRequest(e,"AdminUpdateCoreData",{},9e4)},t.prototype.packageInstall=function(e,t){this.defaultRequest(e,"AdminPackageInstall",{Id:t.id,Type:t.type,File:t.file},6e4)},t.prototype.packageDelete=function(e,t){this.defaultRequest(e,"AdminPackageDelete",{Id:t.id})},t.prototype.domain=function(e,t){this.defaultRequest(e,"AdminDomainLoad",{Name:t})},t.prototype.plugin=function(e,t){this.defaultRequest(e,"AdminPluginLoad",{Name:t})},t.prototype.domainDelete=function(e,t){this.defaultRequest(e,"AdminDomainDelete",{Name:t})},t.prototype.domainDisable=function(e,t,n){return this.defaultRequest(e,"AdminDomainDisable",{Name:t,Disabled:n?"1":"0"})},t.prototype.pluginSettingsUpdate=function(e,t){return this.defaultRequest(e,"AdminPluginSettingsUpdate",t)},t.prototype.licensing=function(e,t){return this.defaultRequest(e,"AdminLicensing",{Force:t?"1":"0"})},t.prototype.licensingActivate=function(e,t,n){return this.defaultRequest(e,"AdminLicensingActivate",{Domain:t,Key:n})},t.prototype.pluginDisable=function(e,t,n){return this.defaultRequest(e,"AdminPluginDisable",{Name:t,Disabled:n?"1":"0"})},t.prototype.createDomainAlias=function(e,t,n){this.defaultRequest(e,"AdminDomainAliasSave",{Name:t,Alias:n})},t.prototype.createOrUpdateDomain=function(e,t,n,i,o,a,r,s,c,l,u,d,p,f,m,h,g,b,v){this.defaultRequest(e,"AdminDomainSave",{Create:t?"1":"0",Name:n,IncHost:i,IncPort:o,IncSecure:a,IncShortLogin:r?"1":"0",UseSieve:s?"1":"0",SieveAllowRaw:c?"1":"0",SieveHost:l,SievePort:u,SieveSecure:d,OutHost:p,OutPort:f,OutSecure:m,OutShortLogin:h?"1":"0",OutAuth:g?"1":"0",OutUsePhpMail:b?"1":"0",WhiteList:v})},t.prototype.testConnectionForDomain=function(e,t,n,i,o,a,r,s,c,l,u,d,p,f){this.defaultRequest(e,"AdminDomainTest",{Name:t,IncHost:n,IncPort:i,IncSecure:o,UseSieve:a?"1":"0",SieveHost:r,SievePort:s,SieveSecure:c,OutHost:l,OutPort:u,OutSecure:d,OutAuth:p?"1":"0",OutUsePhpMail:f?"1":"0"})},t.prototype.testContacts=function(e,t){this.defaultRequest(e,"AdminContactsTest",t)},t.prototype.saveNewAdminPassword=function(e,t){this.defaultRequest(e,"AdminPasswordUpdate",t)},t.prototype.adminPing=function(e){this.defaultRequest(e,"AdminPing")},t}(n(115).a);t.a=new l},function(e,t,n){"use strict";function i(e,t,n){Object(s.isObject)(e)?(n=t||null,t=null,r.a.each(e,function(e,t){i(t,e,n)})):(Object(s.isUnd)(l[e])&&(l[e]=[]),l[e].push([t,n]))}function o(e,t){c.f("rl-pub",[e,t]),Object(s.isUnd)(l[e])||r.a.each(l[e],function(e){e[0]&&e[0].apply(e[1]||null,t||[])})}n.d(t,"b",function(){return i}),n.d(t,"a",function(){return o});var a=n(4),r=n.n(a),s=n(2),c=n(29),l={}},function(e,t,n){"use strict";n.d(t,"i",function(){return i}),n.d(t,"j",function(){return o}),n.d(t,"c",function(){return a}),n.d(t,"g",function(){return r}),n.d(t,"m",function(){return s}),n.d(t,"n",function(){return c}),n.d(t,"l",function(){return l}),n.d(t,"d",function(){return u}),n.d(t,"r",function(){return d}),n.d(t,"b",function(){return p}),n.d(t,"h",function(){return f}),n.d(t,"p",function(){return m}),n.d(t,"o",function(){return h}),n.d(t,"k",function(){return g}),n.d(t,"a",function(){return b}),n.d(t,"q",function(){return v}),n.d(t,"f",function(){return S}),n.d(t,"e",function(){return y});var i=20,o=[10,20,30,50,100],a=50,r=3e4,s=3e5,c=3e5,l=2e5,u=2e5,d="__UNUSE__",p="rlcsc",f=143,m=25,h=4190,g=15,b=7,v=10,S="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC4AAAAuCAYAAABXuSs3AAAHHklEQVRoQ7VZW08bVxCeXRuwIbTGXIwNtBBaqjwgVUiR8lDlbza9qe1DpVZ9aNQ/0KpPeaJK07SpcuEeCEmUAObm21bfrL9lONjexSYrWfbunj37zXdmvpkz9oIgCKTD0Wg0xPd94TDP83Q0zvWa50vzklSrdanVanqf4/D84GBGr+F+Op3S8fqoJxLOdnZgTvsO/nYhenHA+UC7CWF1uXwkb9++ldPTUwVerVbVqFQqpR8YPjQ0JCMjI5LNDijoRgP3PQVu5+5Eor2XGLg7IV4GkIdHJ/LmzRs5ODiIwNbrdR0O0GCcq4Xz4eFhmZyclP7+tDQaIik/BG5XKQn4SwG3zJTLZXn9+rUclI8UHD5YVoDDN8bSzXhONwL48fFxGR4eilzFZT1uFRIB5yT8BqCdnR3Z3d0VP9Un6XRawYJpggVrZBv38ME4XKtUKnLt2jUplUoy1PR/l3U7T6sVSAQcgMAkj8PDQ9ne3pajoyMRL7zeKsYZWHgWYDGmv78/mmdwcFA+mJlSgziHDWrERrsjEXDXegTi1tZW+DLxI2bxIrqFNYTXyDyCFweMAHCwb8e4RnTNuOsqe3t7sra21pTD0Kct666E8XlcZyzw9/RUUXK5nK5oUinUQI6TQ3cynO/v78vq6qrKXCNwlTiJJpyNGc3nZHp6uqV2dwrQWOCtZBDAV1ZWwsQk7f0wiQn5kffbAu/0/KWBYzIC1+XukfGx0RGZmppKlC2tIV0Bh4aDcZW7HhkfH8urLLZL7T2pihvlkMNnz56FiadHxicL41IsFpN41bkxsYxbRdFo9jwB8KdPn14J8KnSpBQKhQs63nPmbCVRcBUAR2Lq1VVmpksyMTFxAXjcEsQybiegESionjx5osCZOeNe1O4+EhCAX7bQSgQcxRHTMgAgcz5+/Dis/hL4uHU3/B4YGNASGHIKxuEql0k+l05AeIAF1vPnz5VxFFmdDlaJrMtZITJeSsXCOTlMunKxjLtMYOKNjQ158eJFuAuKkUOb5sEwgff19SkJUBVkThZUbnXZrtCKBQ6gbnWIkjZpyne3ejAWoGnA7Icz6irvBLgbOMicCM6TkxPx/LAkbXfgWcsazuE2kFRsKD5Z+CiqDumKncpZvieWcS6dDVD8xiYCNflpJdwcdwJOf9airLmVQ7DPzMxIYWLsXGXoVqLt5k0M3K3JUVPDZdbWNzsCp48TPFdvdnZWUz32nDha7bJ63kgAJPzSdRks9/Kf9xMJAQ1gq2NpaUmy2Yz4zar4nQC3xb99AQwCcGzLAAwuhG8YiWvcOKts+r4GOe5nMhm5efOm9lUA3E3vSZJRrKvE0fnPv//Jy5cvo5cTHIPQbSjhOoqq69evS19f6lxDKK4+sVhigZPtKJqbrQeqxd5+WR4+fKgqgT0k2XX3nhiPgETWXFhYkFzuPZ2yVq1GTSOXpE47/VjgNnD4m4GG7/LhsTx69EiwD4Vr2MwIIxgbAH18fKx1yfz8vEogNvGtWnCuhLZa9UTAreVWFsHy/b/+Vrbdl7E5REMQD2jDoUbByty+/ZnU64GkU2HzyJLhktU1cLv8nARgkYS2d3ajAgwG8qU2oLmDZ92CMaOjo7K4uCiZgbDWaRWgnZhPxLhrMUCvr69riwKZk1LHF7XqrWAO9hJxH6ozNzcnCx/PqztZg9mf6SQMscCtm2C5ke4BGMlHWTUp36036AJajDVrFMzBrhhWslQsSrFYiOqVpMriNYIgqFRq2j3FAb/zffT6zuxFXxsNzs3NTXn16lW4gYiW96w1FyedF+83xG/2FNGCRpU4NjamMsn+OZ9xE5RXqdaDdPpib6RWCzuwKF9RxqI2AVNQBwQYJoK0wdBejnqtEikP3pfP51XjUTESl12FqJEKxsEorARYDD44ONTeID7YpsEnrRvQfWAI2e8WfDaTUSIwJ0iBCmFOtOUAHvVMPp/TPwvYFVYFIuP8l+DBgwdaa2Miqwa0GgYwfeMltovbDfh6c1vIgMYcliSsKv4IWFr6VDHxvldvBAH+1sA+cnl5WYOPmmr9ir+1l9I0Cgz0yjhXjfJJ0JROnmezWbl165ayr/5fqwcBNr7IfhjMqKcvESSM4eRcCasQ3bDNObmKPLdGUGpZsN24cUNLBm9zazu4d++e6qpNBFaTuUS26U5dpuR1CxyA7J9ddrMRqlz4pwLLYawymPd++/2PADt2ugcGwq9gCCdhQ96C6xWwa6j1ceuq+I0EhW0i8MAIVJfeL3d/DVD8EKi12P6/2S2jV/EccVB54O/ejz/9HGCpoBBMta5rXMXLu53D1XAwjhXwvvv+h4BAXVe4bOu3O3ChxF08LiZFG3fel199G9CH3fLyqv24NcB44MRhpdK788U3CpyKwsCw590xmfSpzsBt0Fqc3ud3vtZigxWcVZCklVpSiN0w3q5E/h9TGMIUuA3+EQAAAABJRU5ErkJggg==",y="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC"},function(e,t,n){"use strict";n.d(t,"a",function(){return l});var i=n(8),o=n.n(i),a=n(1),r=n(2),s=n(0),c=n(6),l=function(){function e(){o()(this,e),this.bDisabeCloseOnEsc=!1,this.sDefaultKeyScope=s.KeyState.None,this.sCurrentKeyScope=s.KeyState.None,this.viewModelVisibility=a.a.observable(!1),this.modalVisibility=a.a.observable(!1).extend({rateLimit:0}),this.viewModelName="",this.viewModelNames=[],this.viewModelDom=null}return e.prototype.storeAndSetKeyScope=function(){this.sCurrentKeyScope=Object(c.keyScope)(),Object(c.keyScope)(this.sDefaultKeyScope)},e.prototype.restoreKeyScope=function(){Object(c.keyScope)(this.sCurrentKeyScope)},e.prototype.registerPopupKeyDown=function(){var e=this;c.$win.on("keydown",function(t){if(t&&e.modalVisibility&&e.modalVisibility()){if(!e.bDisabeCloseOnEsc&&s.EventKeyCode.Esc===t.keyCode)return Object(r.delegateRun)(e,"cancelCommand"),!1;if(s.EventKeyCode.Backspace===t.keyCode&&!Object(r.inFocus)())return!1}return!0})},e.prototype.cancelCommand=function(){},e.prototype.closeCommand=function(){},e}()},function(e,t,n){"use strict";var i=n(8),o=n.n(i),a=n(3),r=n.n(a),s=n(1),c=n(7),l=n.n(c),u=n(5),d=function(){function e(){var t=this;o()(this,e),this.google={},this.twitter={},this.facebook={},this.dropbox={},this.google.enabled=s.a.observable(!1),this.google.clientID=s.a.observable(""),this.google.clientSecret=s.a.observable(""),this.google.apiKey=s.a.observable(""),this.google.loading=s.a.observable(!1),this.google.userName=s.a.observable(""),this.google.loggined=s.a.computed(function(){return""!==t.google.userName()}),this.google.capa={},this.google.capa.auth=s.a.observable(!1),this.google.capa.authFast=s.a.observable(!1),this.google.capa.drive=s.a.observable(!1),this.google.capa.preview=s.a.observable(!1),this.google.require={},this.google.require.clientSettings=s.a.computed(function(){return t.google.enabled()&&(t.google.capa.auth()||t.google.capa.drive())}),this.google.require.apiKeySettings=s.a.computed(function(){return t.google.enabled()&&t.google.capa.drive()}),this.facebook.enabled=s.a.observable(!1),this.facebook.appID=s.a.observable(""),this.facebook.appSecret=s.a.observable(""),this.facebook.loading=s.a.observable(!1),this.facebook.userName=s.a.observable(""),this.facebook.supported=s.a.observable(!1),this.facebook.loggined=s.a.computed(function(){return""!==t.facebook.userName()}),this.twitter.enabled=s.a.observable(!1),this.twitter.consumerKey=s.a.observable(""),this.twitter.consumerSecret=s.a.observable(""),this.twitter.loading=s.a.observable(!1),this.twitter.userName=s.a.observable(""),this.twitter.loggined=s.a.computed(function(){return""!==t.twitter.userName()}),this.dropbox.enabled=s.a.observable(!1),this.dropbox.apiKey=s.a.observable("")}return e.prototype.populate=function(){this.google.enabled(!!u.settingsGet("AllowGoogleSocial")),this.google.clientID(u.settingsGet("GoogleClientID")),this.google.clientSecret(u.settingsGet("GoogleClientSecret")),this.google.apiKey(u.settingsGet("GoogleApiKey")),this.google.capa.auth(!!u.settingsGet("AllowGoogleSocialAuth")),this.google.capa.authFast(!!u.settingsGet("AllowGoogleSocialAuthFast")),this.google.capa.drive(!!u.settingsGet("AllowGoogleSocialDrive")),this.google.capa.preview(!!u.settingsGet("AllowGoogleSocialPreview")),this.facebook.enabled(!!u.settingsGet("AllowFacebookSocial")),this.facebook.appID(u.settingsGet("FacebookAppID")),this.facebook.appSecret(u.settingsGet("FacebookAppSecret")),this.facebook.supported(!!u.settingsGet("SupportedFacebookSocial")),this.twitter.enabled=s.a.observable(!!u.settingsGet("AllowTwitterSocial")),this.twitter.consumerKey=s.a.observable(u.settingsGet("TwitterConsumerKey")),this.twitter.consumerSecret=s.a.observable(u.settingsGet("TwitterConsumerSecret")),this.dropbox.enabled(!!u.settingsGet("AllowDropboxSocial")),this.dropbox.apiKey(u.settingsGet("DropboxApiKey"))},e.prototype.appendDropbox=function(){if(!r.a.Dropbox&&this.dropbox.enabled()&&this.dropbox.apiKey()&&!r.a.document.getElementById("dropboxjs")){var e=r.a.document.createElement("script");e.type="text/javascript",e.src="https://www.dropbox.com/static/api/2/dropins.js",l()(e).attr("id","dropboxjs").attr("data-app-key",this.dropbox.apiKey()),r.a.document.body.appendChild(e)}},e}();t.a=new d},,function(e,t,n){"use strict";n.d(t,"a",function(){return u}),n.d(t,"b",function(){return d});var i=n(8),o=n.n(i),a=n(7),r=n.n(a),s=n(1),c=n(2),l=n(10),u=function(){function e(){o()(this,e),this.disposable=[]}return e.prototype.dispose=function(){this.disposable.forEach(function(e){e&&e.dispose&&e.dispose()})},e}(),d=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return{template:t?{element:t}:"",viewModel:{createViewModel:function(t,n){return(t=t||{}).element=null,n&&n.element&&(t.component=n,t.element=r()(n.element),Object(l.i18nToNodes)(t.element),!Object(c.isUnd)(t.inline)&&s.a.unwrap(t.inline)&&t.element.css("display","inline-block")),new e(t)}}}}},,function(e,t,n){"use strict";function i(e,t){Object(f.isFunc)(t)&&(Object(f.isArray)(g[e])||(g[e]=[]),g[e].push(t))}function o(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];Object(f.isArray)(g[e])&&p.a.each(g[e],function(e){e.apply(void 0,t)})}function a(e){return h.settingsGet(e)}function r(e,t,n,i){m.data.__APP__&&m.data.__APP__.remote().defaultRequest(e,"Plugin"+t,n,i)}function s(e,t,n,i){b.push([e,t,n,i])}function c(e,t,n,i){v.push([e,t,n,i])}function l(e){var t=n(9);p.a.each(e?v:b,function(e){t.addSettingsViewModel(e[0],e[1],e[2],e[3])})}function u(e,t){var n=h.settingsGet("Plugins");return(n=n&&!Object(f.isUnd)(n[e])?n[e]:null)?Object(f.isUnd)(n[t])?null:n[t]:null}n.d(t,"a",function(){return i}),n.d(t,"f",function(){return o}),n.d(t,"d",function(){return a}),n.d(t,"e",function(){return r}),n.d(t,"b",function(){return s}),n.d(t,"c",function(){return c}),n.d(t,"g",function(){return l}),n.d(t,"h",function(){return u});var d=n(4),p=n.n(d),f=n(2),m=n(6),h=n(5),g={},b=[],v=[]},,,function(e,t,n){"use strict";var i=n(8),o=n.n(i),a=n(1),r=n(2),s=n(5),c=function(){function e(){o()(this,e),this.languages=a.a.observableArray([]),this.languagesAdmin=a.a.observableArray([]),this.language=a.a.observable("").extend({limitedList:this.languages}).extend({reversible:!0}),this.languageAdmin=a.a.observable("").extend({limitedList:this.languagesAdmin}).extend({reversible:!0}),this.userLanguage=a.a.observable(""),this.userLanguageAdmin=a.a.observable("")}return e.prototype.populate=function(){var e=s.appSettingsGet("languages"),t=s.appSettingsGet("languagesAdmin");this.languages(Object(r.isArray)(e)?e:[]),this.languagesAdmin(Object(r.isArray)(t)?t:[]),this.language(s.settingsGet("Language")),this.languageAdmin(s.settingsGet("LanguageAdmin")),this.userLanguage(s.settingsGet("UserLanguage")),this.userLanguageAdmin(s.settingsGet("UserLanguageAdmin"))},e}();t.a=new c},,function(e,t,n){"use strict";function i(){return y(),v||g()()}function o(){return w(),S||0}function a(e){return i().clone().subtract(e,"days").format("YYYY.MM.DD")}function r(e,t){var n=null,a="",r=o();if((n=0<(e=r<(e=0=t.diff(e,"hours"):return e.fromNow();case t.format("L")===e.format("L"):return Object(b.i18n)("MESSAGE_LIST/TODAY_AT",{TIME:e.format("LT")});case t.clone().subtract(1,"days").format("L")===e.format("L"):return Object(b.i18n)("MESSAGE_LIST/YESTERDAY_AT",{TIME:e.format("LT")});case t.year()===e.year():return e.format("D MMM.")}return e?e.format("LL"):""}(n);break;case"FULL":a=n.format("LLL");break;default:a=n.format(t)}return a}function s(e){var t,n="",i=m()(e);(t=i.data("moment-time"))&&((n=i.data("moment-format"))&&i.text(r(t,n)),(n=i.data("moment-format-title"))&&i.attr("title",r(t,n)))}function c(){p.a.defer(function(){m()(".moment",u.a.document).each(function(e,t){s(t)})})}n.r(t),n.d(t,"momentNow",function(){return i}),n.d(t,"momentNowUnix",function(){return o}),n.d(t,"searchSubtractFormatDateHelper",function(){return a}),n.d(t,"format",function(){return r}),n.d(t,"momentToNode",function(){return s}),n.d(t,"reload",function(){return c});var l=n(3),u=n.n(l),d=n(4),p=n.n(d),f=n(7),m=n.n(f),h=n(54),g=n.n(h),b=n(10),v=null,S=0,y=p.a.debounce(function(){v=g()()},500,!0),w=p.a.debounce(function(){S=g()().unix()},500,!0)},function(e,t){e.exports=window.hasher},,function(e,t,n){"use strict";function i(){return n(172).default}n.d(t,"a",function(){return i})},function(e,t,n){"use strict";var i=n(8),o=n.n(i),a=n(12),r=n.n(a),s=n(11),c=n.n(s),l=n(3),u=n.n(l),d=n(7),p=n.n(d),f=n(1),m=n(5),h=function(e){function t(){o()(this,t);var n=r()(this,e.call(this));return n.determineUserLanguage=f.a.observable(!1),n.determineUserDomain=f.a.observable(!1),n.weakPassword=f.a.observable(!1),n.useLocalProxyForExternalImages=f.a.observable(!1),n.dataFolderAccess=f.a.observable(!1),n}return c()(t,e),t.prototype.populate=function(){var t=this;e.prototype.populate.call(this),this.determineUserLanguage(!!Object(m.settingsGet)("DetermineUserLanguage")),this.determineUserDomain(!!Object(m.settingsGet)("DetermineUserDomain")),this.weakPassword(!!Object(m.settingsGet)("WeakPassword")),this.useLocalProxyForExternalImages(!!Object(m.settingsGet)("UseLocalProxyForExternalImages")),Object(m.settingsGet)("Auth")&&p.a.get("./data/VERSION?"+u.a.Math.random()).then(function(){return t.dataFolderAccess(!0)})},t}(n(116).a);t.a=new h},function(e,t,n){"use strict";var i=n(8),o=n.n(i),a=n(1),r=n(2),s=n(5),c=function(){function e(){o()(this,e),this.themes=a.a.observableArray([]),this.themeBackgroundName=a.a.observable(""),this.themeBackgroundHash=a.a.observable(""),this.theme=a.a.observable("").extend({limitedList:this.themes})}return e.prototype.populate=function(){var e=s.appSettingsGet("themes");this.themes(Object(r.isArray)(e)?e:[]),this.theme(s.settingsGet("Theme")),this.themeBackgroundName(s.settingsGet("UserBackgroundName")),this.themeBackgroundHash(s.settingsGet("UserBackgroundHash"))},e}();t.a=new c},function(e,t){var n=e.exports={version:"2.5.1"};"number"==typeof __e&&(__e=n)},function(e,t){var n=e.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=n)},function(e,t,n){e.exports=!n(51)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(e,t,n){var i=n(109),o=n(73);e.exports=function(e){return i(o(e))}},function(e,t,n){"use strict";n.r(t),n.d(t,"EmailModel",function(){return u}),n.d(t,"default",function(){return u});var i=n(8),o=n.n(i),a=n(4),r=n.n(a),s=n(76),c=n.n(s),l=n(2),u=function(){function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"none",a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"";o()(this,e),this.email="",this.name="",this.dkimStatus="",this.dkimValue="",this.email=t,this.name=n,this.dkimStatus=i,this.dkimValue=a,this.clearDuplicateName()}return e.newInstanceFromJson=function(t){var n=new e;return n.initByJson(t)?n:null},e.prototype.clear=function(){this.email="",this.name="",this.dkimStatus="none",this.dkimValue=""},e.prototype.validate=function(){return""!==this.name||""!==this.email},e.prototype.hash=function(){return"#"+(arguments.length>0&&void 0!==arguments[0]&&arguments[0]?"":this.name)+"#"+this.email+"#"},e.prototype.clearDuplicateName=function(){this.name===this.email&&(this.name="")},e.prototype.search=function(e){return-1<(this.name+" "+this.email).toLowerCase().indexOf(e.toLowerCase())},e.prototype.initByJson=function(e){var t=!1;return e&&"Object/Email"===e["@Object"]&&(this.name=Object(l.trim)(e.Name),this.email=Object(l.trim)(e.Email),this.dkimStatus=Object(l.trim)(e.DkimStatus||""),this.dkimValue=Object(l.trim)(e.DkimValue||""),t=""!==this.email,this.clearDuplicateName()),t},e.prototype.toLine=function(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],i="";return""!==this.email&&(e&&""!==this.name?i=t?'
")+'" target="_blank" tabindex="-1">'+Object(l.encodeHtml)(this.name)+"":n?Object(l.encodeHtml)(this.name):this.name:(i=this.email,""!==this.name?t?i=Object(l.encodeHtml)('"'+this.name+'" <')+'")+'" target="_blank" tabindex="-1">'+Object(l.encodeHtml)(i)+""+Object(l.encodeHtml)(">"):(i='"'+this.name+'" <'+i+">",n&&(i=Object(l.encodeHtml)(i))):t&&(i=''+Object(l.encodeHtml)(this.email)+""))),i},e.splitEmailLine=function(t){var n=c()(t);if(Object(l.isNonEmptyArray)(n)){var i=[],o=!1;return n.forEach(function(t){var n=t.address?new e(t.address.replace(/^[<]+(.*)[>]+$/g,"$1"),t.name||""):null;n&&n.email&&(o=!0),i.push(n?n.toLine(!1):t.name)}),o?i:null}return null},e.parseEmailLine=function(t){var n=c()(t);return Object(l.isNonEmptyArray)(n)?r.a.compact(n.map(function(t){return t.address?new e(t.address.replace(/^[<]+(.*)[>]+$/g,"$1"),t.name||""):null})):[]},e.prototype.parse=function(e){if(""===(e=Object(l.trim)(e)))return!1;var t=c()(e);return!(!Object(l.isNonEmptyArray)(t)||!t[0]||(this.name=t[0].name||"",this.email=t[0].address||"",this.clearDuplicateName(),0))},e}()},,function(e,t){var n={}.hasOwnProperty;e.exports=function(e,t){return n.call(e,t)}},function(e,t,n){"use strict";n.d(t,"a",function(){return p});var i=n(8),o=n.n(i),a=n(12),r=n.n(a),s=n(11),c=n.n(s),l=n(1),u=n(2),d=n(0),p=function(e){function t(n){o()(this,t);var i=r()(this,e.call(this));return i.value=n.value||"",i.size=n.size||0,i.label=n.label||"",i.preLabel=n.preLabel||"",i.enable=!!Object(u.isUnd)(n.enable)||n.enable,i.trigger=n.trigger&&n.trigger.subscribe?n.trigger:null,i.placeholder=n.placeholder||"",i.labeled=!Object(u.isUnd)(n.label),i.preLabeled=!Object(u.isUnd)(n.preLabel),i.triggered=!Object(u.isUnd)(n.trigger)&&!!i.trigger,i.classForTrigger=l.a.observable(""),i.className=l.a.computed(function(){var e=l.a.unwrap(i.size),t=i.trigger?" "+Object(u.trim)("settings-saved-trigger-input "+i.classForTrigger()):"";return(01&&void 0!==arguments[1]&&arguments[1];if(!a.a.Promise||!a.a.Promise.all)throw new Error("Promises are not available your environment.");if(!e)throw new Error("src should not be empty.");return new a.a.Promise(function(n,i){var o=a.a.document.createElement("script");o.onload=function(){n(e)},o.onerror=function(){i(new Error(e))},o.async=!0===t,o.src=e,a.a.document.body.appendChild(o)})}n.d(t,"a",function(){return i});var o=n(3),a=n.n(o)},function(e,t,n){var i=n(85)("wks"),o=n(70),a=n(41).Symbol,r="function"==typeof a;(e.exports=function(e){return i[e]||(i[e]=r&&a[e]||(r?a:o)("Symbol."+e))}).store=i},function(e,t,n){var i=n(52);e.exports=function(e){if(!i(e))throw TypeError(e+" is not an object!");return e}},,,function(e,t){e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},function(e,t,n){"use strict";n.d(t,"a",function(){return u});var i=n(8),o=n.n(i),a=n(4),r=n.n(a),s=n(75),c=n.n(s),l=n(2),u=function(){function e(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];o()(this,e),this.oCross=null,this.sScreenName=t,this.aViewModels=Object(l.isArray)(n)?n:[]}return e.prototype.viewModels=function(){return this.aViewModels},e.prototype.screenName=function(){return this.sScreenName},e.prototype.routes=function(){return null},e.prototype.__cross=function(){return this.oCross},e.prototype.__start=function(){var e=null,t=null,n=this.routes();Object(l.isNonEmptyArray)(n)&&(t=r.a.bind(this.onRoute||l.noop,this),e=c.a.create(),n.forEach(function(n){n&&e&&(e.addRoute(n[0],t).rules=n[1])}),this.oCross=e)},e}()},function(e,t){e.exports=window.ssm},function(e,t,n){var i=n(52);e.exports=function(e,t){if(!i(e))return e;var n,o;if(t&&"function"==typeof(n=e.toString)&&!i(o=n.call(e)))return o;if("function"==typeof(n=e.valueOf)&&!i(o=n.call(e)))return o;if(!t&&"function"==typeof(n=e.toString)&&!i(o=n.call(e)))return o;throw TypeError("Can't convert object to primitive value")}},function(e,t,n){"use strict";var i=n(8),o=n.n(i),a=n(1);t.a=new function e(){o()(this,e),this.domains=a.a.observableArray([]),this.domains.loading=a.a.observable(!1).extend({throttle:100}),this.domainsWithoutAliases=this.domains.filter(function(e){return e&&!e.alias})}},,function(e,t){var n=0,i=Math.random();e.exports=function(e){return"Symbol(".concat(void 0===e?"":e,")_",(++n+i).toString(36))}},function(e,t){t.f={}.propertyIsEnumerable},function(e,t,n){var i=n(71),o=n(64),a=n(43),r=n(67),s=n(46),c=n(77),l=Object.getOwnPropertyDescriptor;t.f=n(42)?l:function(e,t){if(e=a(e),t=r(t,!0),c)try{return l(e,t)}catch(e){}if(s(e,t))return o(!i.f.call(e,t),e[t])}},function(e,t){e.exports=function(e){if(void 0==e)throw TypeError("Can't call method on "+e);return e}},function(e,t,n){"use strict";n.d(t,"a",function(){return d});var i=n(8),o=n.n(i),a=n(12),r=n.n(a),s=n(11),c=n.n(s),l=n(1),u=n(2),d=function(e){function t(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};o()(this,t);var i=r()(this,e.call(this));return i.value=n.value,!Object(u.isUnd)(i.value)&&i.value.subscribe||(i.value=l.a.observable(!Object(u.isUnd)(i.value)&&!!i.value)),i.enable=n.enable,!Object(u.isUnd)(i.enable)&&i.enable.subscribe||(i.enable=l.a.observable(!!Object(u.isUnd)(i.enable)||!!i.enable)),i.disable=n.disable,!Object(u.isUnd)(i.disable)&&i.disable.subscribe||(i.disable=l.a.observable(!Object(u.isUnd)(i.disable)&&!!i.disable)),i.label=n.label||"",i.inline=!Object(u.isUnd)(n.inline)&&n.inline,i.readOnly=!Object(u.isUnd)(n.readOnly)&&!!n.readOnly,i.inverted=!Object(u.isUnd)(n.inverted)&&!!n.inverted,i.labeled=!Object(u.isUnd)(n.label),i.labelAnimated=!!n.labelAnimated,i}return c()(t,e),t.prototype.click=function(){this.readOnly||!this.enable()||this.disable()||this.value(!this.value())},t}(n(27).a)},function(e,t){e.exports=window.crossroads},function(e,t,n){"use strict";function i(e){var t=[],n=[],o=[];return new r(e).tokenize().forEach(function(e){"operator"!==e.type||","!==e.value&&";"!==e.value?n.push(e):(n.length&&t.push(n),n=[])}),n.length&&t.push(n),t.forEach(function(e){(e=function(e){for(var t=!1,n="text",o=void 0,a=[],r={address:[],comment:[],group:[],text:[]},s=0,c=e.length;s=0;u--)if(r.text[u].match(/^[^@\s]+@[^@\s]+$/)){r.address=r.text.splice(u,1);break}if(!r.address.length)for(var d=r.text.length-1;d>=0&&(r.text[d]=r.text[d].replace(/\s*\b[^@\s]+@[^@\s]+\b\s*/,function(e){return r.address.length?e:(r.address=[e.trim()]," ")}).trim(),!r.address.length);d--);}if(!r.text.length&&r.comment.length&&(r.text=r.comment,r.comment=[]),r.address.length>1&&(r.text=r.text.concat(r.address.splice(1))),r.text=r.text.join(" "),r.address=r.address.join(" "),!r.address&&t)return[];(o={address:r.address||r.text||"",name:r.text||r.address||""}).address===o.name&&((o.address||"").match(/@/)?o.name="":o.address=""),a.push(o)}return a}(e)).length&&(o=o.concat(e))}),o}Object.defineProperty(t,"__esModule",{value:!0});var o=function(){function e(e,t){for(var n=0;n",",":"",":":";",";":""},r=function(){function e(t){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.str=(t||"").toString(),this.operatorCurrent="",this.operatorExpecting="",this.node=null,this.escaped=!1,this.list=[]}return o(e,[{key:"tokenize",value:function(){for(var e=void 0,t=[],n=0,i=this.str.length;ndocument.F=Object<\/script>"),e.close(),c=e.F;i--;)delete c.prototype[a[i]];return c()};e.exports=Object.create||function(e,t){var n;return null!==e?(s.prototype=i(e),n=new s,s.prototype=null,n[r]=e):n=c(),void 0===t?n:o(n,t)}},function(e,t){e.exports={}},function(e,t){e.exports=!0},function(e,t){var n=Math.ceil,i=Math.floor;e.exports=function(e){return isNaN(e=+e)?0:(e>0?i:n)(e)}},function(e,t){var n={}.toString;e.exports=function(e){return n.call(e).slice(8,-1)}},function(e,t,n){var i=n(52),o=n(41).document,a=i(o)&&i(o.createElement);e.exports=function(e){return a?o.createElement(e):{}}},function(e,t,n){var i=n(112);e.exports=function(e,t,n){if(i(e),void 0===t)return e;switch(n){case 1:return function(n){return e.call(t,n)};case 2:return function(n,i){return e.call(t,n,i)};case 3:return function(n,i,o){return e.call(t,n,i,o)}}return function(){return e.apply(t,arguments)}}},function(e,t,n){"use strict";n.r(t),n.d(t,"HtmlEditor",function(){return m}),n.d(t,"default",function(){return m});var i=n(8),o=n.n(i),a=n(3),r=n.n(a),s=n(4),c=n.n(s),l=n(7),u=n.n(l),d=n(6),p=n(0),f=n(5),m=function(){function e(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null;o()(this,e),this.blurTimer=0,this.__resizable=!1,this.__inited=!1,this.onBlur=null,this.onReady=null,this.onModeChange=null,this.onBlur=n,this.onReady=i,this.onModeChange=a,this.element=t,this.$element=u()(t),this.resize=c.a.throttle(c.a.bind(this.resizeEditor,this),100),this.init()}return e.prototype.runOnBlur=function(){this.onBlur&&this.onBlur()},e.prototype.blurTrigger=function(){var e=this;this.onBlur&&(r.a.clearTimeout(this.blurTimer),this.blurTimer=r.a.setTimeout(function(){e.runOnBlur()},p.Magics.Time200ms))},e.prototype.focusTrigger=function(){this.onBlur&&r.a.clearTimeout(this.blurTimer)},e.prototype.isHtml=function(){return!!this.editor&&"wysiwyg"===this.editor.mode},e.prototype.clearCachedSignature=function(){this.editor&&this.editor.execCommand("insertSignature",{clearCache:!0})},e.prototype.setSignature=function(e,t){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];this.editor&&this.editor.execCommand("insertSignature",{isHtml:t,insertBefore:n,signature:e})},e.prototype.checkDirty=function(){return!!this.editor&&this.editor.checkDirty()},e.prototype.resetDirty=function(){this.editor&&this.editor.resetDirty()},e.prototype.getData=function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],t="";if(this.editor)try{t="plain"===this.editor.mode&&this.editor.plugins.plain&&this.editor.__plain?this.editor.__plain.getRawData():e?'
'+this.editor.getData()+"
":this.editor.getData()}catch(e){}return t},e.prototype.getDataWithHtmlMark=function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];return(this.isHtml()?":HTML:":"")+this.getData(e)},e.prototype.modeToggle=function(e,t){if(this.editor){try{e?"plain"===this.editor.mode&&this.editor.setMode("wysiwyg"):"wysiwyg"===this.editor.mode&&this.editor.setMode("plain")}catch(e){}t&&this.resize()}},e.prototype.setHtmlOrPlain=function(e,t){":HTML:"===e.substr(0,6)?this.setHtml(e.substr(6),t):this.setPlain(e,t)},e.prototype.setHtml=function(e,t){if(this.editor&&this.__inited){this.clearCachedSignature(),this.modeToggle(!0),e=e.replace(/]*><\/p>/gi,"");try{this.editor.setData(e)}catch(e){}t&&this.focus()}},e.prototype.replaceHtml=function(e,t){if(this.editor&&this.__inited&&"wysiwyg"===this.editor.mode)try{this.editor.setData(this.editor.getData().replace(e,t))}catch(e){}},e.prototype.setPlain=function(e,t){if(this.editor&&this.__inited){if(this.clearCachedSignature(),this.modeToggle(!1),"plain"===this.editor.mode&&this.editor.plugins.plain&&this.editor.__plain)this.editor.__plain.setRawData(e);else try{this.editor.setData(e)}catch(e){}t&&this.focus()}},e.prototype.init=function(){var e=this;if(this.element&&!this.editor){var t=function(){var t=d.htmlEditorDefaultConfig,n=f.settingsGet("Language"),i=!!f.appSettingsGet("allowHtmlEditorSourceButton"),o=!!f.appSettingsGet("allowHtmlEditorBitiButtons");!i&&o||t.toolbarGroups.__cfgInited||(t.toolbarGroups.__cfgInited=!0,i&&(t.removeButtons=t.removeButtons.replace(",Source","")),o||(t.removePlugins+=(t.removePlugins?",":"")+"bidi")),t.enterMode=r.a.CKEDITOR.ENTER_BR,t.shiftEnterMode=r.a.CKEDITOR.ENTER_P,t.language=d.htmlEditorLangsMap[(n||"en").toLowerCase()]||"en",r.a.CKEDITOR.env&&(r.a.CKEDITOR.env.isCompatible=!0),e.editor=r.a.CKEDITOR.appendTo(e.element,t),e.editor.on("key",function(e){return!e||!e.data||p.EventKeyCode.Tab!==e.data.keyCode}),e.editor.on("blur",function(){e.blurTrigger()}),e.editor.on("mode",function(){e.blurTrigger(),e.onModeChange&&e.onModeChange("plain"!==e.editor.mode)}),e.editor.on("focus",function(){e.focusTrigger()}),r.a.FileReader&&e.editor.on("drop",function(t){if(0')},o.readAsDataURL(n),t.data.dataTransfer.setData("text/html",i)}}}),e.editor.on("instanceReady",function(){e.editor.removeMenuItem&&(e.editor.removeMenuItem("cut"),e.editor.removeMenuItem("copy"),e.editor.removeMenuItem("paste")),e.__resizable=!0,e.__inited=!0,e.resize(),e.onReady&&e.onReady()})};r.a.CKEDITOR?t():r.a.__initEditor=t}},e.prototype.focus=function(){if(this.editor)try{this.editor.focus()}catch(e){}},e.prototype.hasFocus=function(){if(this.editor)try{return!!this.editor.focusManager.hasFocus}catch(e){}return!1},e.prototype.blur=function(){if(this.editor)try{this.editor.focusManager.blur(!0)}catch(e){}},e.prototype.resizeEditor=function(){if(this.editor&&this.__resizable)try{this.editor.resize(this.$element.width(),this.$element.innerHeight())}catch(e){}},e.prototype.setReadOnly=function(e){if(this.editor)try{this.editor.setReadOnly(!!e)}catch(e){}},e.prototype.clear=function(e){this.setHtml("",e)},e}()},function(e,t){e.exports=window.Autolinker},function(e,t,n){!function(t,i){"use strict";var o;try{o=n(54)}catch(e){}e.exports=function(e){var t="function"==typeof e,n=!!window.addEventListener,i=window.document,o=window.setTimeout,a=function(e,t,i,o){n?e.addEventListener(t,i,!!o):e.attachEvent("on"+t,i)},r=function(e,t,i,o){n?e.removeEventListener(t,i,!!o):e.detachEvent("on"+t,i)},s=function(e,t){return-1!==(" "+e.className+" ").indexOf(" "+t+" ")},c=function(e){return/Array/.test(Object.prototype.toString.call(e))},l=function(e){return/Date/.test(Object.prototype.toString.call(e))&&!isNaN(e.getTime())},u=function(e){var t=e.getDay();return 0===t||6===t},d=function(e,t){return[31,function(e){return e%4==0&&e%100!=0||e%400==0}(e)?29:28,31,30,31,30,31,31,30,31,30,31][t]},p=function(e){l(e)&&e.setHours(0,0,0,0)},f=function(e,t){return e.getTime()===t.getTime()},m=function(e,t,n){var i,o;for(i in t)(o=void 0!==e[i])&&"object"==typeof t[i]&&null!==t[i]&&void 0===t[i].nodeName?l(t[i])?n&&(e[i]=new Date(t[i].getTime())):c(t[i])?n&&(e[i]=t[i].slice(0)):e[i]=m({},t[i],n):!n&&o||(e[i]=t[i]);return e},h=function(e,t,n){var o;i.createEvent?((o=i.createEvent("HTMLEvents")).initEvent(t,!0,!1),o=m(o,n),e.dispatchEvent(o)):i.createEventObject&&(o=i.createEventObject(),o=m(o,n),e.fireEvent("on"+t,o))},g=function(e){return e.month<0&&(e.year-=Math.ceil(Math.abs(e.month)/12),e.month+=12),e.month>11&&(e.year+=Math.floor(Math.abs(e.month)/12),e.month-=12),e},b={field:null,bound:void 0,position:"bottom left",reposition:!0,format:"YYYY-MM-DD",toString:null,parse:null,defaultDate:null,setDefaultDate:!1,firstDay:0,formatStrict:!1,minDate:null,maxDate:null,yearRange:10,showWeekNumber:!1,pickWholeWeek:!1,minYear:0,maxYear:9999,minMonth:void 0,maxMonth:void 0,startRange:null,endRange:null,isRTL:!1,yearSuffix:"",showMonthAfterYear:!1,showDaysInNextAndPreviousMonths:!1,enableSelectionDaysInNextAndPreviousMonths:!1,numberOfMonths:1,mainCalendar:"left",container:void 0,blurFieldOnSelect:!0,i18n:{previousMonth:"Previous Month",nextMonth:"Next Month",months:["January","February","March","April","May","June","July","August","September","October","November","December"],weekdays:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],weekdaysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"]},theme:null,events:[],onSelect:null,onOpen:null,onClose:null,onDraw:null,keyboardInput:!0},v=function(e,t,n){for(t+=e.firstDay;t>=7;)t-=7;return n?e.i18n.weekdaysShort[t]:e.i18n.weekdays[t]},S=function(e){var t=[],n="false";if(e.isEmpty){if(!e.showDaysInNextAndPreviousMonths)return'';t.push("is-outside-current-month"),e.enableSelectionDaysInNextAndPreviousMonths||t.push("is-selection-disabled")}return e.isDisabled&&t.push("is-disabled"),e.isToday&&t.push("is-today"),e.isSelected&&(t.push("is-selected"),n="true"),e.hasEvent&&t.push("has-event"),e.isInRange&&t.push("is-inrange"),e.isStartRange&&t.push("is-startrange"),e.isEndRange&&t.push("is-endrange"),'"},y=function(e,t,n,i){return''+(t?e.reverse():e).join("")+""},w=function(e,t,n,i,o,a){var r,s,l,u,d,p=e._o,f=n===p.minYear,m=n===p.maxYear,h='
',g=!0,b=!0;for(l=[],r=0;r<12;r++)l.push('");for(u='
'+p.i18n.months[i]+'
",c(p.yearRange)?(r=p.yearRange[0],s=p.yearRange[1]+1):(r=n-p.yearRange,s=1+n+p.yearRange),l=[];r=p.minYear&&l.push('");return d='
'+n+p.yearSuffix+'
",p.showMonthAfterYear?h+=d+u:h+=u+d,f&&(0===i||p.minMonth>=i)&&(g=!1),m&&(11===i||p.maxMonth<=i)&&(b=!1),0===t&&(h+='"),t===e._o.numberOfMonths-1&&(h+='"),h+="
"},A=function(r){var c=this,u=c.config(r);c._onMouseDown=function(e){if(c._v){var t=(e=e||window.event).target||e.srcElement;if(t)if(s(t,"is-disabled")||(!s(t,"pika-button")||s(t,"is-empty")||s(t.parentNode,"is-disabled")?s(t,"pika-prev")?c.prevMonth():s(t,"pika-next")&&c.nextMonth():(c.setDate(new Date(t.getAttribute("data-pika-year"),t.getAttribute("data-pika-month"),t.getAttribute("data-pika-day"))),u.bound&&o(function(){c.hide(),u.blurFieldOnSelect&&u.field&&u.field.blur()},100))),s(t,"pika-select"))c._c=!0;else{if(!e.preventDefault)return e.returnValue=!1,!1;e.preventDefault()}}},c._onChange=function(e){var t=(e=e||window.event).target||e.srcElement;t&&(s(t,"pika-select-month")?c.gotoMonth(t.value):s(t,"pika-select-year")&&c.gotoYear(t.value))},c._onKeyChange=function(e){if(e=e||window.event,c.isVisible())switch(e.keyCode){case 13:case 27:u.field&&u.field.blur();break;case 37:e.preventDefault(),c.adjustDate("subtract",1);break;case 38:c.adjustDate("subtract",7);break;case 39:c.adjustDate("add",1);break;case 40:c.adjustDate("add",7)}},c._onInputChange=function(n){var i;n.firedBy!==c&&(i=u.parse?u.parse(u.field.value,u.format):t?(i=e(u.field.value,u.format,u.formatStrict))&&i.isValid()?i.toDate():null:new Date(Date.parse(u.field.value)),l(i)&&c.setDate(i),c._v||c.show())},c._onInputFocus=function(){c.show()},c._onInputClick=function(){c.show()},c._onInputBlur=function(){var e=i.activeElement;do{if(s(e,"pika-single"))return}while(e=e.parentNode);c._c||(c._b=o(function(){c.hide()},50)),c._c=!1},c._onClick=function(e){var t=(e=e||window.event).target||e.srcElement,i=t;if(t){!n&&s(t,"pika-select")&&(t.onchange||(t.setAttribute("onchange","return;"),a(t,"change",c._onChange)));do{if(s(i,"pika-single")||i===u.trigger)return}while(i=i.parentNode);c._v&&t!==u.trigger&&i!==u.trigger&&c.hide()}},c.el=i.createElement("div"),c.el.className="pika-single"+(u.isRTL?" is-rtl":"")+(u.theme?" "+u.theme:""),a(c.el,"mousedown",c._onMouseDown,!0),a(c.el,"touchend",c._onMouseDown,!0),a(c.el,"change",c._onChange),u.keyboardInput&&a(i,"keydown",c._onKeyChange),u.field&&(u.container?u.container.appendChild(c.el):u.bound?i.body.appendChild(c.el):u.field.parentNode.insertBefore(c.el,u.field.nextSibling),a(u.field,"change",c._onInputChange),u.defaultDate||(t&&u.field.value?u.defaultDate=e(u.field.value,u.format).toDate():u.defaultDate=new Date(Date.parse(u.field.value)),u.setDefaultDate=!0));var d=u.defaultDate;l(d)?u.setDefaultDate?c.setDate(d,!0):c.gotoDate(d):c.gotoDate(new Date),u.bound?(this.hide(),c.el.className+=" is-bound",a(u.trigger,"click",c._onInputClick),a(u.trigger,"focus",c._onInputFocus),a(u.trigger,"blur",c._onInputBlur)):this.show()};return A.prototype={config:function(e){this._o||(this._o=m({},b,!0));var t=m(this._o,e,!0);t.isRTL=!!t.isRTL,t.field=t.field&&t.field.nodeName?t.field:null,t.theme="string"==typeof t.theme&&t.theme?t.theme:null,t.bound=!!(void 0!==t.bound?t.field&&t.bound:t.field),t.trigger=t.trigger&&t.trigger.nodeName?t.trigger:t.field,t.disableWeekends=!!t.disableWeekends,t.disableDayFn="function"==typeof t.disableDayFn?t.disableDayFn:null;var n=parseInt(t.numberOfMonths,10)||1;if(t.numberOfMonths=n>4?4:n,l(t.minDate)||(t.minDate=!1),l(t.maxDate)||(t.maxDate=!1),t.minDate&&t.maxDate&&t.maxDate100&&(t.yearRange=100);return t},toString:function(n){return n=n||this._o.format,l(this._d)?this._o.toString?this._o.toString(this._d,n):t?e(this._d).format(n):this._d.toDateString():""},getMoment:function(){return t?e(this._d):null},setMoment:function(n,i){t&&e.isMoment(n)&&this.setDate(n.toDate(),i)},getDate:function(){return l(this._d)?new Date(this._d.getTime()):null},setDate:function(e,t){if(!e)return this._d=null,this._o.field&&(this._o.field.value="",h(this._o.field,"change",{firedBy:this})),this.draw();if("string"==typeof e&&(e=new Date(Date.parse(e))),l(e)){var n=this._o.minDate,i=this._o.maxDate;l(n)&&ei&&(e=i),this._d=new Date(e.getTime()),p(this._d),this.gotoDate(this._d),this._o.field&&(this._o.field.value=this.toString(),h(this._o.field,"change",{firedBy:this})),t||"function"!=typeof this._o.onSelect||this._o.onSelect.call(this,this.getDate())}},gotoDate:function(e){var t=!0;if(l(e)){if(this.calendars){var n=new Date(this.calendars[0].year,this.calendars[0].month,1),i=new Date(this.calendars[this.calendars.length-1].year,this.calendars[this.calendars.length-1].month,1),o=e.getTime();i.setMonth(i.getMonth()+1),i.setDate(i.getDate()-1),t=o=a&&(this._y=a,!isNaN(s)&&this._m>s&&(this._m=s)),t="pika-title-"+Math.random().toString(36).replace(/[^a-z]+/g,"").substr(0,2);for(var l=0;l'+w(this,l,this.calendars[l].year,this.calendars[l].month,this.calendars[0].year,t)+this.render(this.calendars[l].year,this.calendars[l].month,t)+"";this.el.innerHTML=c,n.bound&&"hidden"!==n.field.type&&o(function(){n.trigger.focus()},1),"function"==typeof this._o.onDraw&&this._o.onDraw(this),n.bound&&n.field.setAttribute("aria-label","Use the arrow keys to pick a date")}},adjustPosition:function(){var e,t,n,o,a,r,s,c,l,u;if(!this._o.container){if(this.el.style.position="absolute",t=e=this._o.trigger,n=this.el.offsetWidth,o=this.el.offsetHeight,a=window.innerWidth||i.documentElement.clientWidth,r=window.innerHeight||i.documentElement.clientHeight,s=window.pageYOffset||i.body.scrollTop||i.documentElement.scrollTop,"function"==typeof e.getBoundingClientRect)c=(u=e.getBoundingClientRect()).left+window.pageXOffset,l=u.bottom+window.pageYOffset;else for(c=t.offsetLeft,l=t.offsetTop+t.offsetHeight;t=t.offsetParent;)c+=t.offsetLeft,l+=t.offsetTop;(this._o.reposition&&c+n>a||this._o.position.indexOf("right")>-1&&c-n+e.offsetWidth>0)&&(c=c-n+e.offsetWidth),(this._o.reposition&&l+o>r+s||this._o.position.indexOf("top")>-1&&l-o-e.offsetHeight>0)&&(l=l-o-e.offsetHeight),this.el.style.left=c+"px",this.el.style.top=l+"px"}},render:function(e,t,n){var i=this._o,o=new Date,a=d(e,t),r=new Date(e,t,1).getDay(),s=[],c=[];p(o),i.firstDay>0&&(r-=i.firstDay)<0&&(r+=7);for(var m=0===t?11:t-1,h=11===t?0:t+1,g=0===t?e-1:e,b=11===t?e+1:e,w=d(g,m),A=a+r,O=A;O>7;)O-=7;A+=7-O;for(var T,C,_,E,D=!1,N=0,j=0;N=a+r,L=N-r+1,M=t,F=e,U=i.startRange&&f(i.startRange,R),H=i.endRange&&f(i.endRange,R),G=i.startRange&&i.endRange&&i.startRangei.maxDate||i.disableWeekends&&u(R)||i.disableDayFn&&i.disableDayFn(R);k&&(N'+Math.ceil(((new Date(_,C,T)-E)/864e5+E.getDay()+1)/7)+"")),s.push(y(c,i.isRTL,i.pickWholeWeek,D)),c=[],j=0,D=!1)}return function(e,t,n){return''+function(e){var t,n=[];for(e.showWeekNumber&&n.push(""),t=0;t<7;t++)n.push('");return""+(e.isRTL?n.reverse():n).join("")+""}(i)+""+t.join("")+"
'+v(e,t,!0)+"
"}(0,s,n)},isVisible:function(){return this._v},show:function(){var e,t,n;this.isVisible()||(this._v=!0,this.draw(),e=this.el,t="is-hidden",e.className=(n=(" "+e.className+" ").replace(" "+t+" "," ")).trim?n.trim():n.replace(/^\s+|\s+$/g,""),this._o.bound&&(a(i,"click",this._onClick),this.adjustPosition()),"function"==typeof this._o.onOpen&&this._o.onOpen.call(this))},hide:function(){var e,t,n=this._v;!1!==n&&(this._o.bound&&r(i,"click",this._onClick),this.el.style.position="static",this.el.style.left="auto",this.el.style.top="auto",e=this.el,s(e,t="is-hidden")||(e.className=""===e.className?t:e.className+" "+t),this._v=!1,void 0!==n&&"function"==typeof this._o.onClose&&this._o.onClose.call(this))},destroy:function(){var e=this._o;this.hide(),r(this.el,"mousedown",this._onMouseDown,!0),r(this.el,"touchend",this._onMouseDown,!0),r(this.el,"change",this._onChange),e.keyboardInput&&r(i,"keydown",this._onKeyChange),e.field&&(r(e.field,"change",this._onInputChange),e.bound&&(r(e.trigger,"click",this._onInputClick),r(e.trigger,"focus",this._onInputFocus),r(e.trigger,"blur",this._onInputBlur))),this.el.parentNode&&this.el.parentNode.removeChild(this.el)}},A}(o)}()},,function(e,t,n){"use strict";n.r(t),n.d(t,"AskPopupView",function(){return v}),n.d(t,"default",function(){return v});var i,o=n(8),a=n.n(o),r=n(12),s=n.n(r),c=n(11),l=n.n(c),u=n(1),d=n(19),p=n.n(d),f=n(0),m=n(2),h=n(10),g=n(9),b=n(24),v=Object(g.popup)({name:"View/Popup/Ask",templateID:"PopupsAsk"})(i=function(e){function t(){a()(this,t);var n=s()(this,e.call(this));return n.askDesc=u.a.observable(""),n.yesButton=u.a.observable(""),n.noButton=u.a.observable(""),n.yesFocus=u.a.observable(!1),n.noFocus=u.a.observable(!1),n.fYesAction=null,n.fNoAction=null,n.bFocusYesOnShow=!0,n.bDisabeCloseOnEsc=!0,n.sDefaultKeyScope=f.KeyState.PopupAsk,n}return l()(t,e),t.prototype.clearPopup=function(){this.askDesc(""),this.yesButton(Object(h.i18n)("POPUPS_ASK/BUTTON_YES")),this.noButton(Object(h.i18n)("POPUPS_ASK/BUTTON_NO")),this.yesFocus(!1),this.noFocus(!1),this.fYesAction=null,this.fNoAction=null},t.prototype.yesClick=function(){this.cancelCommand(),Object(m.isFunc)(this.fYesAction)&&this.fYesAction.call(null)},t.prototype.noClick=function(){this.cancelCommand(),Object(m.isFunc)(this.fNoAction)&&this.fNoAction.call(null)},t.prototype.onShow=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"",o=arguments.length>4&&void 0!==arguments[4]?arguments[4]:"",a=!(arguments.length>5&&void 0!==arguments[5])||arguments[5];this.clearPopup(),this.fYesAction=t||null,this.fNoAction=n||null,this.askDesc(e||""),i&&this.yesButton(i),o&&this.noButton(o),this.bFocusYesOnShow=!!a},t.prototype.onShowWithDelay=function(){this.bFocusYesOnShow&&this.yesFocus(!0)},t.prototype.onBuild=function(){var e=this;p()("tab, shift+tab, right, left",f.KeyState.PopupAsk,function(){return e.yesFocus()?e.noFocus(!0):e.yesFocus(!0),!1}),p()("esc",f.KeyState.PopupAsk,function(){return e.noClick(),!1})},t}(b.a))||i},,function(e,t,n){"use strict";n.r(t),n.d(t,"LanguagesPopupView",function(){return g}),n.d(t,"default",function(){return g});var i,o=n(8),a=n.n(o),r=n(12),s=n.n(r),c=n(11),l=n.n(c),u=n(4),d=n.n(u),p=n(1),f=n(2),m=n(9),h=n(24),g=Object(m.popup)({name:"View/Popup/Languages",templateID:"PopupsLanguages"})(i=function(e){function t(){a()(this,t);var n=s()(this,e.call(this));return n.fLang=null,n.userLanguage=p.a.observable(""),n.langs=p.a.observableArray([]),n.languages=p.a.computed(function(){var e=n.userLanguage();return d.a.map(n.langs(),function(t){return{key:t,user:t===e,selected:p.a.observable(!1),fullName:Object(f.convertLangName)(t)}})}),n.langs.subscribe(function(){n.setLanguageSelection()}),n}return l()(t,e),t.prototype.languageTooltipName=function(e){var t=Object(f.convertLangName)(e,!0);return Object(f.convertLangName)(e,!1)===t?"":t},t.prototype.setLanguageSelection=function(){var e=this.fLang?p.a.unwrap(this.fLang):"";d.a.each(this.languages(),function(t){t.selected(t.key===e)})},t.prototype.onBeforeShow=function(){this.fLang=null,this.userLanguage(""),this.langs([])},t.prototype.onShow=function(e,t,n){this.fLang=e,this.userLanguage(n||""),this.langs(t)},t.prototype.changeLanguage=function(e){this.fLang&&this.fLang(e),this.cancelCommand()},t}(h.a))||i},function(e,t,n){var i=n(104),o=n(84).concat("length","prototype");t.f=Object.getOwnPropertyNames||function(e){return i(e,o)}},function(e,t){t.f=Object.getOwnPropertySymbols},function(e,t,n){var i=n(46),o=n(43),a=n(163)(!1),r=n(86)("IE_PROTO");e.exports=function(e,t){var n,s=o(e),c=0,l=[];for(n in s)n!=r&&i(s,n)&&l.push(n);for(;t.length>c;)i(s,n=t[c++])&&(~a(l,n)||l.push(n));return l}},function(e,t,n){e.exports=n(53)},function(e,t,n){"use strict";var i=n(90),o=n(58),a=n(105),r=n(53),s=n(46),c=n(89),l=n(165),u=n(83),d=n(159),p=n(60)("iterator"),f=!([].keys&&"next"in[].keys()),m=function(){return this};e.exports=function(e,t,n,h,g,b,v){l(n,t,h);var S,y,w,A=function(e){if(!f&&e in _)return _[e];switch(e){case"keys":case"values":return function(){return new n(this,e)}}return function(){return new n(this,e)}},O=t+" Iterator",T="values"==g,C=!1,_=e.prototype,E=_[p]||_["@@iterator"]||g&&_[g],D=E||A(g),N=g?T?A("entries"):D:void 0,j="Array"==t&&_.entries||E;if(j&&(w=d(j.call(new e)))!==Object.prototype&&w.next&&(u(w,O,!0),i||s(w,p)||r(w,p,m)),T&&E&&"values"!==E.name&&(C=!0,D=function(){return E.call(this)}),i&&!v||!f&&!C&&_[p]||r(_,p,D),c[t]=D,c[O]=m,g)if(S={values:T?D:A("values"),keys:b?D:A("keys"),entries:N},v)for(y in S)y in _||a(_,y,S[y]);else o(o.P+o.F*(f||C),t,S);return S}},function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}t.__esModule=!0;var o=i(n(169)),a=i(n(153)),r="function"==typeof a.default&&"symbol"==typeof o.default?function(e){return typeof e}:function(e){return e&&"function"==typeof a.default&&e.constructor===a.default&&e!==a.default.prototype?"symbol":typeof e};t.default="function"==typeof a.default&&"symbol"===r(o.default)?function(e){return void 0===e?"undefined":r(e)}:function(e){return e&&"function"==typeof a.default&&e.constructor===a.default&&e!==a.default.prototype?"symbol":void 0===e?"undefined":r(e)}},function(e,t,n){var i=n(58),o=n(40),a=n(51);e.exports=function(e,t){var n=(o.Object||{})[e]||Object[e],r={};r[e]=t(n),i(i.S+i.F*a(function(){n(1)}),"Object",r)}},function(e,t,n){var i=n(92);e.exports=Object("z").propertyIsEnumerable(0)?Object:function(e){return"String"==i(e)?e.split(""):Object(e)}},function(e,t,n){var i=n(43),o=n(72).f;n(108)("getOwnPropertyDescriptor",function(){return function(e,t){return o(i(e),t)}})},function(e,t,n){n(110);var i=n(40).Object;e.exports=function(e,t){return i.getOwnPropertyDescriptor(e,t)}},function(e,t){e.exports=function(e){if("function"!=typeof e)throw TypeError(e+" is not a function!");return e}},function(e,t,n){"use strict";function i(){var e;null===N&&((N=f()("
")).appendTo(w.$body),e=N,j||(j=new R(e),g.a.applyBindingAccessorsToNode(e[0],{translatorInit:!0,template:function(){return{name:"Cmd"}}},j)))}var o=n(8),a=n.n(o),r=n(12),s=n.n(r),c=n(11),l=n.n(c),u=n(3),d=n.n(u),p=n(7),f=n.n(p),m=n(4),h=n.n(m),g=n(1),b=n(19),v=n.n(b),S=n(66),y=n.n(S),w=n(6),A=n(2),O=n(0),T=n(16),C=n(10),_=n(5),E=n(39),D=n(32),N=null,j=null,R=function(){function e(t){a()(this,e),this.dom=null,this.opened=g.a.observable(!1),this.cmd=g.a.observable(""),this.focused=g.a.observable(!1),this.themes=E.a.themes,this.cmdHistory=[],this.cmdHistoryShift=0,this.cmdHelper=g.a.observable(""),this.cmds=["help","version","clear","theme","lang"],this.cmdsWithParameters=["theme","lang"],this.isAdmin=!1,this.dom=t,this.isAdmin=!!_.appSettingsGet("admin")}return e.prototype.runCmd=function(e,t,i){var o,a,r,s="",c=null;if(this.cmdHelper(""),i){switch(e){case"lang":c=(this.isAdmin?D.a.languagesAdmin():D.a.languages()).filter(function(e){return 0===e.lastIndexOf(t,0)});break;case"theme":c=E.a.themes().filter(function(e){return 0===e.lastIndexOf(t,0)})}if(e&&c)if(1===c.length&&c[0])this.cmd(e+" "+c[0]);else if(1").html(n(129).replace("{{ cmd }}",i))),c&&l.append(f()("
").html(c)),h.a.delay(function(){t.dom.find(".rl-cmd-history").scrollTop(l.height())},50))}return!0},e.prototype.onEsc=function(){return this.opened(!1),!1},e.prototype.onTab=function(){return this.onCmd(!0),!1},e.prototype.onEnter=function(){return this.onCmd(!1),this.cmd(""),!1},e.prototype.onKeyDown=function(e){if(e&&e.keyCode&&!e.metaKey&&!e.ctrlKey&&!e.shiftKey&&0').appendTo("body"),w.$win.on("error",function(e){if(e&&e.originalEvent&&e.originalEvent.message&&-1===Object(A.inArray)(e.originalEvent.message,["Script error.","Uncaught Error: Error calling method on NPObject."])){var t=Object(A.timestamp)();if(o.lastErrorTime>=t)return;o.lastErrorTime=t,n.jsError(A.noop,e.originalEvent.message,e.originalEvent.filename,e.originalEvent.lineno,d.a.location&&d.a.location.toString?d.a.location.toString():"",w.$html.attr("class"),Object(A.microtime)()-w.startMicrotime)}}),w.$win.on("resize",function(){I.a("window.resize")}),I.b("window.resize",h.a.throttle(function(){var e=w.$win.height(),t=w.$win.height();w.$win.__sizes[0]===e&&w.$win.__sizes[1]===t||(w.$win.__sizes[0]=e,w.$win.__sizes[1]=t,I.a("window.resize.real"))},O.Magics.Time50ms)),w.$doc.on("keydown",function(e){e&&e.ctrlKey&&w.$html.addClass("rl-ctrl-key-pressed")}).on("keyup",function(e){e&&!e.ctrlKey&&w.$html.removeClass("rl-ctrl-key-pressed")}),w.$doc.on("mousemove keypress click",h.a.debounce(function(){I.a("rl.auto-logout-refresh")},O.Magics.Time5s)),v()("esc, enter",O.KeyState.All,function(){Object(A.detectDropdownVisibility)()}),_.appSettingsGet("allowCmdInterface")&&v()("ctrl+shift+`",O.KeyState.All,function(){_.appSettingsGet("allowCmdInterface")&&(i(),h.a.delay(function(){j&&(j.opened(!j.opened()),j.opened()&&h.a.delay(function(){j&&j.focused&&j.focused(!0)},O.Magics.Time50ms))},O.Magics.Time50ms))}),o}return l()(t,e),t.prototype.remote=function(){return null},t.prototype.data=function(){return null},t.prototype.getApplicationConfiguration=function(e,t){return this.applicationConfiguration[e]||t},t.prototype.download=function(e){if(w.sUserAgent&&(-10&&void 0!==arguments[0]&&arguments[0],t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],i=!!_.appSettingsGet("inIframe"),o=Object(A.pString)(_.appSettingsGet("customLogoutLink"));t&&this.clearClientSideToken(),t&&n&&d.a.close&&d.a.close(),o=o||(e?Object(T.x)():Object(T.y)()),t&&d.a.location.href!==o?h.a.delay(function(){i&&d.a.parent?d.a.parent.location.href=o:d.a.location.href=o,w.$win.trigger("rl.tooltips.diactivate")},O.Magics.Time100ms):(Object(P.routeOff)(),Object(P.setHash)(Object(T.w)(),!0),Object(P.routeOff)(),h.a.delay(function(){i&&d.a.parent?d.a.parent.location.reload():d.a.location.reload(),w.$win.trigger("rl.tooltips.diactivate")},O.Magics.Time100ms))},t.prototype.historyBack=function(){d.a.history.back()},t.prototype.bootstart=function(){I.a("rl.bootstart");var e=_.appSettingsGet("mobile");g.a.components.register("SaveTrigger",n(128).default),g.a.components.register("Input",n(127).default),g.a.components.register("Select",n(126).default),g.a.components.register("Radio",n(121).default),g.a.components.register("TextArea",n(125).default),g.a.components.register("Date",n(124).default),g.a.components.register("x-script",n(123).default),_.appSettingsGet("materialDesign")&&w.bAnimationSupported?(g.a.components.register("Checkbox",n(122).default),g.a.components.register("CheckboxSimple",n(80).default)):(g.a.components.register("Checkbox",n(80).default),g.a.components.register("CheckboxSimple",n(80).default)),Object(C.initOnStartOrLangChange)(C.initNotificationLanguage),h.a.delay(A.windowResizeCallback,O.Magics.Time1s),I.b("ssm.mobile-enter",function(){Object(w.leftPanelDisabled)(!0)}),I.b("ssm.mobile-leave",function(){Object(w.leftPanelDisabled)(!1)}),e?(w.$html.addClass("ssm-state-mobile").addClass("rl-mobile"),I.a("ssm.mobile-enter")):(w.$html.addClass("rl-desktop"),y.a.addState({id:"mobile",query:"(max-width: 767px)",onEnter:function(){w.$html.addClass("ssm-state-mobile"),I.a("ssm.mobile-enter")},onLeave:function(){w.$html.removeClass("ssm-state-mobile"),I.a("ssm.mobile-leave")}}),y.a.addState({id:"tablet",query:"(min-width: 768px) and (max-width: 999px)",onEnter:function(){w.$html.addClass("ssm-state-tablet")},onLeave:function(){w.$html.removeClass("ssm-state-tablet")}}),y.a.addState({id:"desktop",query:"(min-width: 1000px) and (max-width: 1400px)",onEnter:function(){w.$html.addClass("ssm-state-desktop")},onLeave:function(){w.$html.removeClass("ssm-state-desktop")}}),y.a.addState({id:"desktop-large",query:"(min-width: 1401px)",onEnter:function(){w.$html.addClass("ssm-state-desktop-large")},onLeave:function(){w.$html.removeClass("ssm-state-desktop-large")}})),w.leftPanelDisabled.subscribe(function(e){w.$html.toggleClass("rl-left-panel-disabled",e),w.$html.toggleClass("rl-left-panel-enabled",!e)}),w.leftPanelType.subscribe(function(e){w.$html.toggleClass("rl-left-panel-none","none"===e),w.$html.toggleClass("rl-left-panel-short","short"===e)}),w.leftPanelDisabled.valueHasMutated(),D.a.populate(),E.a.populate(),x.a.populate()},t}(k)},function(e,t,n){"use strict";n.d(t,"a",function(){return v});var i=n(8),o=n.n(i),a=n(12),r=n.n(a),s=n(11),c=n.n(s),l=n(4),u=n.n(l),d=n(7),p=n.n(d),f=n(1),m=n(6),h=n(2),g=n(16),b=n(9),v=function(e){function t(n){o()(this,t);var i=r()(this,e.call(this,"settings",n));return i.menu=f.a.observableArray([]),i.oCurrentSubScreen=null,i.oViewModelPlace=null,i.setupSettings(),i}return c()(t,e),t.prototype.setupSettings=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;e&&e()},t.prototype.onRoute=function(e){var t=this,n=null,i=null,o=null,a=null;if((i=u.a.find(m.VIEW_MODELS.settings,function(t){return t&&t.__rlSettingsData&&e===t.__rlSettingsData.Route}))&&(u.a.find(m.VIEW_MODELS["settings-removed"],function(e){return e&&e===i})&&(i=null),i&&u.a.find(m.VIEW_MODELS["settings-disabled"],function(e){return e&&e===i})&&(i=null)),i){if(i.__builded&&i.__vm)n=i.__vm;else if((o=this.oViewModelPlace)&&1===o.length){n=new i,(a=p()("
").addClass("rl-settings-view-model").hide()).appendTo(o),n.viewModelDom=a,n.__rlSettingsData=i.__rlSettingsData,i.__dom=a,i.__builded=!0,i.__vm=n;var r={name:i.__rlSettingsData.Template};f.a.applyBindingAccessorsToNode(a[0],{translatorInit:!0,template:function(){return r}},n),Object(h.delegateRun)(n,"onBuild",[a])}else Object(h.log)("Cannot find sub settings view model position: SettingsSubScreen");n&&u.a.defer(function(){t.oCurrentSubScreen&&(Object(h.delegateRun)(t.oCurrentSubScreen,"onHide"),t.oCurrentSubScreen.viewModelDom.hide()),t.oCurrentSubScreen=n,t.oCurrentSubScreen&&(Object(h.delegateRun)(t.oCurrentSubScreen,"onBeforeShow"),t.oCurrentSubScreen.viewModelDom.show(),Object(h.delegateRun)(t.oCurrentSubScreen,"onShow"),Object(h.delegateRun)(t.oCurrentSubScreen,"onShowWithDelay",[],200),u.a.each(t.menu(),function(e){e.selected(n&&n.__rlSettingsData&&e.route===n.__rlSettingsData.Route)}),p()("#rl-content .b-settings .b-content .content").scrollTop(0)),Object(h.windowResize)()})}else Object(b.setHash)(Object(g.z)(),!1,!0)},t.prototype.onHide=function(){this.oCurrentSubScreen&&this.oCurrentSubScreen.viewModelDom&&(Object(h.delegateRun)(this.oCurrentSubScreen,"onHide"),this.oCurrentSubScreen.viewModelDom.hide())},t.prototype.onBuild=function(){var e=this;u.a.each(m.VIEW_MODELS.settings,function(t){t&&t.__rlSettingsData&&!u.a.find(m.VIEW_MODELS["settings-removed"],function(e){return e&&e===t})&&e.menu.push({route:t.__rlSettingsData.Route,label:t.__rlSettingsData.Label,selected:f.a.observable(!1),disabled:!!u.a.find(m.VIEW_MODELS["settings-disabled"],function(e){return e&&e===t})})}),this.oViewModelPlace=p()("#rl-content #rl-settings-subscreen")},t.prototype.routes=function(){var e=u.a.find(m.VIEW_MODELS.settings,function(e){return e&&e.__rlSettingsData&&e.__rlSettingsData.IsDefault}),t=e&&e.__rlSettingsData?e.__rlSettingsData.Route:"general",n={subname:/^(.*)$/,normalize_:function(e,n){return n.subname=Object(h.isUnd)(n.subname)?t:Object(h.pString)(n.subname),[n.subname]}};return[["{subname}/",n],["{subname}",n],["",n]]},t}(n(65).a)},function(e,t,n){"use strict";n.d(t,"a",function(){return v});var i=n(8),o=n.n(i),a=n(3),r=n.n(a),s=n(4),c=n.n(s),l=n(7),u=n.n(l),d=n(23),p=n(0),f=n(2),m=n(6),h=n(16),g=n(29),b=n(5),v=function(){function e(){o()(this,e),this.oRequests={}}return e.prototype.defaultResponse=function(e,t,n,i,o,a){var r=function(){p.StorageResultType.Success!==n&&m.data.bUnload&&(n=p.StorageResultType.Unload),p.StorageResultType.Success===n&&i&&!i.Result?(i&&-12&&void 0!==arguments[2]?arguments[2]:2e4,o=this,a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"",s=arguments.length>4&&void 0!==arguments[4]?arguments[4]:[],l=""===a,d=(new r.a.Date).getTime();(n=(t=t||{}).Action||"")&&0(new r.a.Date).getTime()-d),n&&o.oRequests[n]&&(o.oRequests[n].__aborted&&(a="abort"),o.oRequests[n]=null),o.defaultResponse(e,n,a,i,s,t)}),n&&03&&void 0!==arguments[3]&&arguments[3];this.defaultRequest(e,"JsInfo",{Type:t,Data:n,IsError:i?"1":"0"})},e.prototype.getPublicKey=function(e){this.defaultRequest(e,"GetPublicKey")},e.prototype.jsVersion=function(e,t){this.defaultRequest(e,"Version",{Version:t})},e}()},function(e,t,n){"use strict";n.d(t,"a",function(){return c});var i=n(8),o=n.n(i),a=n(1),r=n(6),s=n(5),c=function(){function e(){o()(this,e),this.allowLanguagesOnSettings=a.a.observable(!0),this.allowLanguagesOnLogin=a.a.observable(!0),this.newMoveToFolder=a.a.observable(!0),this.interfaceAnimation=a.a.observable(!0),this.interfaceAnimation.subscribe(function(e){var t=r.bMobileDevice||!e;r.$html.toggleClass("rl-anim",!t).toggleClass("no-rl-anim",t)}),this.interfaceAnimation.valueHasMutated(),this.prem=a.a.observable(!1),this.community=a.a.observable(!0)}return e.prototype.populate=function(){this.allowLanguagesOnLogin(!!s.settingsGet("AllowLanguagesOnLogin")),this.allowLanguagesOnSettings(!!s.settingsGet("AllowLanguagesOnSettings")),this.newMoveToFolder(!!s.settingsGet("NewMoveToFolder")),this.interfaceAnimation(!!s.settingsGet("InterfaceAnimation")),this.prem(!!s.settingsGet("PremType")),this.community(!!s.settingsGet("Community"))},e}()},function(e,t,n){"use strict";var i=n(3),o=n.n(i),a=n(2),r=n(6),s=n(0),c=n(29),l=n(10),u=n(44);t.a=function(e){r.data.__APP__=e,r.$win.on("keydown",a.killCtrlACtrlS).on("unload",function(){r.data.bUnload=!0}),r.$html.addClass(r.bMobileDevice?"mobile":"no-mobile").on("click.dropdown.data-api",a.detectDropdownVisibility);var t=o.a.rl||{};t.i18n=l.i18n,t.createCommand=a.createCommandLegacy,t.addSettingsViewModel=c.b,t.addSettingsViewModelForAdmin=c.c,t.addHook=c.a,t.settingsGet=c.d,t.pluginSettingsGet=c.h,t.pluginRemoteRequest=c.e,t.EmailModel=u.EmailModel,t.Enums=s,o.a.rl=t,o.a.__APP_BOOT=function(t){Object(a.domReady)(function(){o.a.setTimeout(function(){o.a.rainloopTEMPLATES&&o.a.rainloopTEMPLATES[0]?(o.a.document.getElementById("rl-templates").innerHTML=o.a.rainloopTEMPLATES[0],o.a.setTimeout(function(){r.$html.removeClass("no-js rl-booted-trigger").addClass("rl-booted"),e.bootstart()},s.Magics.Time10ms)):t(),o.a.__APP_BOOT=null},s.Magics.Time10ms)})}}},,,,function(e,t,n){"use strict";n.r(t);var i=n(8),o=n.n(i),a=n(12),r=n.n(a),s=n(11),c=n.n(s),l=n(27),u=n(4),d=n.n(u),p=n(1),f=n(2),m=function(e){function t(){return o()(this,t),r()(this,e.apply(this,arguments))}return c()(t,e),t}(function(e){function t(n){o()(this,t);var i=r()(this,e.call(this));return i.values=p.a.observableArray([]),i.value=n.value,!Object(f.isUnd)(i.value)&&i.value.subscribe||(i.value=p.a.observable("")),i.inline=!Object(f.isUnd)(n.inline)&&n.inline,i.readOnly=!Object(f.isUnd)(n.readOnly)&&!!n.readOnly,n.values&&i.values(d.a.map(n.values,function(e,t){return{label:e,value:t}})),i.click=d.a.bind(i.click,i),i}return c()(t,e),t.prototype.click=function(e){!this.readOnly&&e&&this.value(e.value)},t}(l.a));t.default=Object(l.b)(m,"RadioComponent")},function(e,t,n){"use strict";n.r(t);var i=n(8),o=n.n(i),a=n(12),r=n.n(a),s=n(11),c=n.n(s),l=n(4),u=n.n(l),d=n(1),p=n(27),f=function(e){function t(n){o()(this,t);var i=r()(this,e.call(this,n));return i.animationBox=d.a.observable(!1).extend({falseTimeout:200}),i.animationCheckmark=d.a.observable(!1).extend({falseTimeout:200}),i.animationBoxSetTrue=u.a.bind(i.animationBoxSetTrue,i),i.animationCheckmarkSetTrue=u.a.bind(i.animationCheckmarkSetTrue,i),i.disposable.push(i.value.subscribe(function(e){i.triggerAnimation(e)},i)),i}return c()(t,e),t.prototype.animationBoxSetTrue=function(){this.animationBox(!0)},t.prototype.animationCheckmarkSetTrue=function(){this.animationCheckmark(!0)},t.prototype.triggerAnimation=function(e){e?(this.animationBoxSetTrue(),u.a.delay(this.animationCheckmarkSetTrue,200)):(this.animationCheckmarkSetTrue(),u.a.delay(this.animationBoxSetTrue,200))},t}(n(74).a);t.default=Object(p.b)(f,"CheckboxMaterialDesignComponent")},function(e,t,n){"use strict";n.r(t);var i=n(8),o=n.n(i),a=n(12),r=n.n(a),s=n(11),c=n.n(s),l=n(7),u=n.n(l),d=n(27),p=function(e){function t(n){o()(this,t);var i=r()(this,e.call(this));if(n.component&&n.component.templateNodes&&n.element&&n.element[0]&&n.element[0].outerHTML){var a=n.element[0].outerHTML;(a=a?a.replace(/<\/b><\/x-script>/i,"<\/script>"):"")?(n.element.text(""),n.element.replaceWith(u()(a).text(n.component.templateNodes[0]&&n.component.templateNodes[0].nodeValue?n.component.templateNodes[0].nodeValue:""))):n.element.remove()}return i}return c()(t,e),t}(d.a);t.default=Object(d.b)(p,"ScriptComponent")},function(e,t,n){"use strict";n.r(t);var i=n(8),o=n.n(i),a=n(12),r=n.n(a),s=n(11),c=n.n(s),l=n(27),u=function(e){function t(){return o()(this,t),r()(this,e.apply(this,arguments))}return c()(t,e),t}(n(47).a);t.default=Object(l.b)(u,"DateComponent")},function(e,t,n){"use strict";n.r(t);var i=n(8),o=n.n(i),a=n(12),r=n.n(a),s=n(11),c=n.n(s),l=n(2),u=n(27),d=5,p=function(e){function t(n){o()(this,t);var i=r()(this,e.call(this,n));return i.rows=n.rows||d,i.spellcheck=!Object(l.isUnd)(n.spellcheck)&&!!n.spellcheck,i}return c()(t,e),t}(n(47).a);t.default=Object(u.b)(p,"TextAreaComponent")},function(e,t,n){"use strict";n.r(t);var i=n(8),o=n.n(i),a=n(12),r=n.n(a),s=n(11),c=n.n(s),l=n(10),u=n(2),d=n(27),p=function(e){function t(n){o()(this,t);var i=r()(this,e.call(this,n));return i.options=n.options||"",i.optionsText=n.optionsText||null,i.optionsValue=n.optionsValue||null,i.optionsCaption=n.optionsCaption||null,i.optionsCaption&&(i.optionsCaption=Object(l.i18n)(i.optionsCaption)),i.defautOptionsAfterRender=u.defautOptionsAfterRender,i}return c()(t,e),t}(n(47).a);t.default=Object(d.b)(p,"SelectComponent")},function(e,t,n){"use strict";n.r(t);var i=n(8),o=n.n(i),a=n(12),r=n.n(a),s=n(11),c=n.n(s),l=n(27),u=function(e){function t(){return o()(this,t),r()(this,e.apply(this,arguments))}return c()(t,e),t}(n(47).a);t.default=Object(l.b)(u,"InputComponent")},function(e,t,n){"use strict";n.r(t);var i=n(8),o=n.n(i),a=n(12),r=n.n(a),s=n(11),c=n.n(s),l=n(2),u=n(0),d=n(27),p=function(e){function t(n){o()(this,t);var i=r()(this,e.call(this));return i.element=n.element||null,i.value=n.value&&n.value.subscribe?n.value:null,i.element&&(i.value?(i.element.css("display","inline-block"),n.verticalAlign&&i.element.css("vertical-align",n.verticalAlign),i.setState(i.value()),i.disposable.push(i.value.subscribe(i.setState,i))):i.element.hide()),i}return c()(t,e),t.prototype.setState=function(e){switch(Object(l.pInt)(e)){case u.SaveSettingsStep.TrueResult:this.element.find(".animated,.error").hide().removeClass("visible").end().find(".success").show().addClass("visible");break;case u.SaveSettingsStep.FalseResult:this.element.find(".animated,.success").hide().removeClass("visible").end().find(".error").show().addClass("visible");break;case u.SaveSettingsStep.Animate:this.element.find(".error,.success").hide().removeClass("visible").end().find(".animated").show().addClass("visible");break;case u.SaveSettingsStep.Idle:default:this.element.find(".animated").hide().end().find(".error,.success").removeClass("visible")}},t}(d.a);t.default=Object(d.b)(p,"SaveTriggerComponent")},function(e,t){e.exports='> {{ cmd }}'},function(e,t){e.exports=' version: {{ version }}'},function(e,t){e.exports='lang [{{ langs }}]'},function(e,t){e.exports='theme [{{ themes }}]'},function(e,t){e.exports=' commands: {{ commands }}'},function(e,t){e.exports='Command not found: {{ cmd }}'},,,function(e,t,n){var i=n(58);i(i.S,"Object",{create:n(88)})},function(e,t,n){n(137);var i=n(40).Object;e.exports=function(e,t){return i.create(e,t)}},function(e,t,n){e.exports={default:n(138),__esModule:!0}},function(e,t,n){var i=n(52),o=n(61),a=function(e,t){if(o(e),!i(t)&&null!==t)throw TypeError(t+": can't set as prototype!")};e.exports={set:Object.setPrototypeOf||("__proto__"in{}?function(e,t,i){try{(i=n(94)(Function.call,n(72).f(Object.prototype,"__proto__").set,2))(e,[]),t=!(e instanceof Array)}catch(e){t=!0}return function(e,n){return a(e,n),t?e.__proto__=n:i(e,n),e}}({},!1):void 0),check:a}},function(e,t,n){var i=n(58);i(i.S,"Object",{setPrototypeOf:n(140).set})},function(e,t,n){n(141),e.exports=n(40).Object.setPrototypeOf},function(e,t,n){e.exports={default:n(142),__esModule:!0}},function(e,t,n){n(81)("observable")},function(e,t,n){n(81)("asyncIterator")},function(e,t){},function(e,t,n){var i=n(43),o=n(102).f,a={}.toString,r="object"==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[];e.exports.f=function(e){return r&&"[object Window]"==a.call(e)?function(e){try{return o(e)}catch(e){return r.slice()}}(e):o(i(e))}},function(e,t,n){var i=n(92);e.exports=Array.isArray||function(e){return"Array"==i(e)}},function(e,t,n){var i=n(87),o=n(103),a=n(71);e.exports=function(e){var t=i(e),n=o.f;if(n)for(var r,s=n(e),c=a.f,l=0;s.length>l;)c.call(e,r=s[l++])&&t.push(r);return t}},function(e,t,n){var i=n(70)("meta"),o=n(52),a=n(46),r=n(49).f,s=0,c=Object.isExtensible||function(){return!0},l=!n(51)(function(){return c(Object.preventExtensions({}))}),u=function(e){r(e,i,{value:{i:"O"+ ++s,w:{}}})},d=e.exports={KEY:i,NEED:!1,fastKey:function(e,t){if(!o(e))return"symbol"==typeof e?e:("string"==typeof e?"S":"P")+e;if(!a(e,i)){if(!c(e))return"F";if(!t)return"E";u(e)}return e[i].i},getWeak:function(e,t){if(!a(e,i)){if(!c(e))return!0;if(!t)return!1;u(e)}return e[i].w},onFreeze:function(e){return l&&d.NEED&&c(e)&&!a(e,i)&&u(e),e}}},function(e,t,n){"use strict";var i=n(41),o=n(46),a=n(42),r=n(58),s=n(105),c=n(150).KEY,l=n(51),u=n(85),d=n(83),p=n(70),f=n(60),m=n(82),h=n(81),g=n(149),b=n(148),v=n(61),S=n(43),y=n(67),w=n(64),A=n(88),O=n(147),T=n(72),C=n(49),_=n(87),E=T.f,D=C.f,N=O.f,j=i.Symbol,R=i.JSON,I=R&&R.stringify,x=f("_hidden"),P=f("toPrimitive"),k={}.propertyIsEnumerable,L=u("symbol-registry"),M=u("symbols"),F=u("op-symbols"),U=Object.prototype,H="function"==typeof j,G=i.QObject,B=!G||!G.prototype||!G.prototype.findChild,V=a&&l(function(){return 7!=A(D({},"a",{get:function(){return D(this,"a",{value:7}).a}})).a})?function(e,t,n){var i=E(U,t);i&&delete U[t],D(e,t,n),i&&e!==U&&D(U,t,i)}:D,q=function(e){var t=M[e]=A(j.prototype);return t._k=e,t},z=H&&"symbol"==typeof j.iterator?function(e){return"symbol"==typeof e}:function(e){return e instanceof j},K=function(e,t,n){return e===U&&K(F,t,n),v(e),t=y(t,!0),v(n),o(M,t)?(n.enumerable?(o(e,x)&&e[x][t]&&(e[x][t]=!1),n=A(n,{enumerable:w(0,!1)})):(o(e,x)||D(e,x,w(1,{})),e[x][t]=!0),V(e,t,n)):D(e,t,n)},W=function(e,t){v(e);for(var n,i=g(t=S(t)),o=0,a=i.length;a>o;)K(e,n=i[o++],t[n]);return e},Y=function(e){var t=k.call(this,e=y(e,!0));return!(this===U&&o(M,e)&&!o(F,e))&&(!(t||!o(this,e)||!o(M,e)||o(this,x)&&this[x][e])||t)},$=function(e,t){if(e=S(e),t=y(t,!0),e!==U||!o(M,t)||o(F,t)){var n=E(e,t);return!n||!o(M,t)||o(e,x)&&e[x][t]||(n.enumerable=!0),n}},J=function(e){for(var t,n=N(S(e)),i=[],a=0;n.length>a;)o(M,t=n[a++])||t==x||t==c||i.push(t);return i},X=function(e){for(var t,n=e===U,i=N(n?F:S(e)),a=[],r=0;i.length>r;)!o(M,t=i[r++])||n&&!o(U,t)||a.push(M[t]);return a};H||(s((j=function(){if(this instanceof j)throw TypeError("Symbol is not a constructor!");var e=p(arguments.length>0?arguments[0]:void 0),t=function(n){this===U&&t.call(F,n),o(this,x)&&o(this[x],e)&&(this[x][e]=!1),V(this,e,w(1,n))};return a&&B&&V(U,e,{configurable:!0,set:t}),q(e)}).prototype,"toString",function(){return this._k}),T.f=$,C.f=K,n(102).f=O.f=J,n(71).f=Y,n(103).f=X,a&&!n(90)&&s(U,"propertyIsEnumerable",Y,!0),m.f=function(e){return q(f(e))}),r(r.G+r.W+r.F*!H,{Symbol:j});for(var Q="hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables".split(","),Z=0;Q.length>Z;)f(Q[Z++]);for(var ee=_(f.store),te=0;ee.length>te;)h(ee[te++]);r(r.S+r.F*!H,"Symbol",{for:function(e){return o(L,e+="")?L[e]:L[e]=j(e)},keyFor:function(e){if(!z(e))throw TypeError(e+" is not a symbol!");for(var t in L)if(L[t]===e)return t},useSetter:function(){B=!0},useSimple:function(){B=!1}}),r(r.S+r.F*!H,"Object",{create:function(e,t){return void 0===t?A(e):W(A(e),t)},defineProperty:K,defineProperties:W,getOwnPropertyDescriptor:$,getOwnPropertyNames:J,getOwnPropertySymbols:X}),R&&r(r.S+r.F*(!H||l(function(){var e=j();return"[null]"!=I([e])||"{}"!=I({a:e})||"{}"!=I(Object(e))})),"JSON",{stringify:function(e){if(void 0!==e&&!z(e)){for(var t,n,i=[e],o=1;arguments.length>o;)i.push(arguments[o++]);return"function"==typeof(t=i[1])&&(n=t),!n&&b(t)||(t=function(e,t){if(n&&(t=n.call(this,e,t)),!z(t))return t}),i[1]=t,I.apply(R,i)}}}),j.prototype[P]||n(53)(j.prototype,P,j.prototype.valueOf),d(j,"Symbol"),d(Math,"Math",!0),d(i.JSON,"JSON",!0)},function(e,t,n){n(151),n(146),n(145),n(144),e.exports=n(40).Symbol},function(e,t,n){e.exports={default:n(152),__esModule:!0}},function(e,t){e.exports=function(e,t){return{value:t,done:!!e}}},function(e,t){e.exports=function(){}},function(e,t,n){"use strict";var i=n(155),o=n(154),a=n(89),r=n(43);e.exports=n(106)(Array,"Array",function(e,t){this._t=r(e),this._i=0,this._k=t},function(){var e=this._t,t=this._k,n=this._i++;return!e||n>=e.length?(this._t=void 0,o(1)):o(0,"keys"==t?n:"values"==t?e[n]:[n,e[n]])},"values"),a.Arguments=a.Array,i("keys"),i("values"),i("entries")},function(e,t,n){n(156);for(var i=n(41),o=n(53),a=n(89),r=n(60)("toStringTag"),s="CSSRuleList,CSSStyleDeclaration,CSSValueList,ClientRectList,DOMRectList,DOMStringList,DOMTokenList,DataTransferItemList,FileList,HTMLAllCollection,HTMLCollection,HTMLFormElement,HTMLSelectElement,MediaList,MimeTypeArray,NamedNodeMap,NodeList,PaintRequestList,Plugin,PluginArray,SVGLengthList,SVGNumberList,SVGPathSegList,SVGPointList,SVGStringList,SVGTransformList,SourceBufferList,StyleSheetList,TextTrackCueList,TextTrackList,TouchList".split(","),c=0;c0?o(i(e),9007199254740991):0}},function(e,t,n){var i=n(43),o=n(162),a=n(161);e.exports=function(e){return function(t,n,r){var s,c=i(t),l=o(c.length),u=a(r,l);if(e&&n!=n){for(;l>u;)if((s=c[u++])!=s)return!0}else for(;l>u;u++)if((e||u in c)&&c[u]===n)return e||u||0;return!e&&-1}}},function(e,t,n){var i=n(49),o=n(61),a=n(87);e.exports=n(42)?Object.defineProperties:function(e,t){o(e);for(var n,r=a(t),s=r.length,c=0;s>c;)i.f(e,n=r[c++],t[n]);return e}},function(e,t,n){"use strict";var i=n(88),o=n(64),a=n(83),r={};n(53)(r,n(60)("iterator"),function(){return this}),e.exports=function(e,t,n){e.prototype=i(r,{next:o(1,n)}),a(e,t+" Iterator")}},function(e,t,n){var i=n(91),o=n(73);e.exports=function(e){return function(t,n){var a,r,s=String(o(t)),c=i(n),l=s.length;return c<0||c>=l?e?"":void 0:(a=s.charCodeAt(c))<55296||a>56319||c+1===l||(r=s.charCodeAt(c+1))<56320||r>57343?e?s.charAt(c):a:e?s.slice(c,c+2):r-56320+(a-55296<<10)+65536}}},function(e,t,n){"use strict";var i=n(166)(!0);n(106)(String,"String",function(e){this._t=String(e),this._i=0},function(){var e,t=this._t,n=this._i;return n>=t.length?{value:void 0,done:!0}:(e=i(t,n),this._i+=e.length,{value:e,done:!1})})},function(e,t,n){n(167),n(157),e.exports=n(82).f("iterator")},function(e,t,n){e.exports={default:n(168),__esModule:!0}},function(e,t){e.exports='\n\n\t\n\t\n\t\n\t\n\t{{title}}\n\t\n\n\n\t
\n\t\t
{{subject}}
\n\t
\n\t
\n\t\t
{{date}}
\n\t\t
{{fromCreds}}
\n\t\t
{{toLabel}}: {{toCreds}}
\n\t\t
{{ccLabel}}: {{ccCreds}}
\n\t
\n\t
{{html}}
\n\n'},,function(e,t,n){"use strict";n.r(t);var i,o,a,r,s,c,l,u,d,p,f,m,h,g,b,v,S=n(8),y=n.n(S),w=n(12),A=n.n(w),O=n(11),T=n.n(O),C=n(3),_=n.n(C),E=n(4),D=n.n(E),N=n(1),j=n(55),R=n.n(j),I=n(16),x=n(10),P=n(0),k=n(2),L=n(5),M=n(38),F=n(48),U=n(68),H=new function e(){y()(this,e),this.plugins=N.a.observableArray([]),this.plugins.loading=N.a.observable(!1).extend({throttle:100}),this.plugins.error=N.a.observable("")},G=new function e(){y()(this,e),this.licensing=N.a.observable(!1),this.licensingProcess=N.a.observable(!1),this.licenseValid=N.a.observable(!1),this.licenseExpired=N.a.observable(0),this.licenseError=N.a.observable(""),this.licenseTrigger=N.a.observable(!1)},B=new function e(){y()(this,e),this.packages=N.a.observableArray([]),this.packages.loading=N.a.observable(!1).extend({throttle:100}),this.packagesReal=N.a.observable(!0),this.packagesMainUpdatable=N.a.observable(!0)},V=new function e(){y()(this,e),this.coreReal=N.a.observable(!0),this.coreChannel=N.a.observable("stable"),this.coreType=N.a.observable("stable"),this.coreUpdatable=N.a.observable(!0),this.coreAccess=N.a.observable(!0),this.coreWarning=N.a.observable(!1),this.coreChecking=N.a.observable(!1).extend({throttle:100}),this.coreUpdating=N.a.observable(!1).extend({throttle:100}),this.coreVersion=N.a.observable(""),this.coreRemoteVersion=N.a.observable(""),this.coreRemoteRelease=N.a.observable(""),this.coreVersionCompare=N.a.observable(-2)},q=n(21),z=n(9),K=n(29),W=n(114),Y=n(39),$=n(32),J=function(){function e(){var t=this;y()(this,e),this.language=$.a.language,this.languages=$.a.languages,this.languageAdmin=$.a.languageAdmin,this.languagesAdmin=$.a.languagesAdmin,this.theme=Y.a.theme,this.themes=Y.a.themes,this.capaThemes=F.a.themes,this.capaUserBackground=F.a.userBackground,this.capaGravatar=F.a.gravatar,this.capaAdditionalAccounts=F.a.additionalAccounts,this.capaIdentities=F.a.identities,this.capaAttachmentThumbnails=F.a.attachmentThumbnails,this.capaTemplates=F.a.templates,this.allowLanguagesOnSettings=M.a.allowLanguagesOnSettings,this.weakPassword=M.a.weakPassword,this.newMoveToFolder=M.a.newMoveToFolder,this.dataFolderAccess=M.a.dataFolderAccess,this.mainAttachmentLimit=N.a.observable(Object(k.pInt)(Object(L.settingsGet)("AttachmentLimit"))/(P.Magics.BitLength1024*P.Magics.BitLength1024)).extend({posInterer:25}),this.uploadData=Object(L.settingsGet)("PhpUploadSizes"),this.uploadDataDesc=this.uploadData&&(this.uploadData.upload_max_filesize||this.uploadData.post_max_size)?[this.uploadData.upload_max_filesize?"upload_max_filesize = "+this.uploadData.upload_max_filesize+"; ":"",this.uploadData.post_max_size?"post_max_size = "+this.uploadData.post_max_size:""].join(""):"",this.themesOptions=N.a.computed(function(){return D.a.map(t.themes(),function(e){return{optValue:e,optText:Object(k.convertThemeName)(e)}})}),this.languageFullName=N.a.computed(function(){return Object(k.convertLangName)(t.language())}),this.languageAdminFullName=N.a.computed(function(){return Object(k.convertLangName)(t.languageAdmin())}),this.attachmentLimitTrigger=N.a.observable(P.SaveSettingsStep.Idle),this.languageTrigger=N.a.observable(P.SaveSettingsStep.Idle),this.languageAdminTrigger=N.a.observable(P.SaveSettingsStep.Idle).extend({throttle:P.Magics.Time100ms}),this.themeTrigger=N.a.observable(P.SaveSettingsStep.Idle)}return e.prototype.onBuild=function(){var e=this;D.a.delay(function(){var t=Object(k.settingsSaveHelperSimpleFunction)(e.attachmentLimitTrigger,e),n=Object(k.settingsSaveHelperSimpleFunction)(e.languageTrigger,e),i=Object(k.settingsSaveHelperSimpleFunction)(e.themeTrigger,e),o=function(t){return function(){e.languageAdminTrigger(t),D.a.delay(function(){return e.languageAdminTrigger(P.SaveSettingsStep.Idle)},P.Magics.Time1s)}};e.mainAttachmentLimit.subscribe(function(e){q.a.saveAdminConfig(t,{AttachmentLimit:Object(k.pInt)(e)})}),e.language.subscribe(function(e){q.a.saveAdminConfig(n,{Language:Object(k.trim)(e)})}),e.languageAdmin.subscribe(function(t){e.languageAdminTrigger(P.SaveSettingsStep.Animate),Object(x.reload)(!0,t).then(o(P.SaveSettingsStep.TrueResult),o(P.SaveSettingsStep.FalseResult)).then(function(){q.a.saveAdminConfig(null,{LanguageAdmin:Object(k.trim)(t)})})}),e.theme.subscribe(function(t){Object(k.changeTheme)(t,e.themeTrigger),q.a.saveAdminConfig(i,{Theme:Object(k.trim)(t)})}),e.capaAdditionalAccounts.subscribe(function(e){q.a.saveAdminConfig(null,{CapaAdditionalAccounts:Object(k.boolToAjax)(e)})}),e.capaIdentities.subscribe(function(e){q.a.saveAdminConfig(null,{CapaIdentities:Object(k.boolToAjax)(e)})}),e.capaTemplates.subscribe(function(e){q.a.saveAdminConfig(null,{CapaTemplates:Object(k.boolToAjax)(e)})}),e.capaGravatar.subscribe(function(e){q.a.saveAdminConfig(null,{CapaGravatar:Object(k.boolToAjax)(e)})}),e.capaAttachmentThumbnails.subscribe(function(e){q.a.saveAdminConfig(null,{CapaAttachmentThumbnails:Object(k.boolToAjax)(e)})}),e.capaThemes.subscribe(function(e){q.a.saveAdminConfig(null,{CapaThemes:Object(k.boolToAjax)(e)})}),e.capaUserBackground.subscribe(function(e){q.a.saveAdminConfig(null,{CapaUserBackground:Object(k.boolToAjax)(e)})}),e.allowLanguagesOnSettings.subscribe(function(e){q.a.saveAdminConfig(null,{AllowLanguagesOnSettings:Object(k.boolToAjax)(e)})}),e.newMoveToFolder.subscribe(function(e){q.a.saveAdminConfig(null,{NewMoveToFolder:Object(k.boolToAjax)(e)})})},P.Magics.Time50ms)},e.prototype.selectLanguage=function(){Object(z.showScreenPopup)(n(101),[this.language,this.languages(),$.a.userLanguage()])},e.prototype.selectLanguageAdmin=function(){Object(z.showScreenPopup)(n(101),[this.languageAdmin,this.languagesAdmin(),$.a.userLanguageAdmin()])},e.prototype.phpInfoLink=function(){return Object(I.u)()},e}(),X=n(37),Q=function(){function e(){var t=this;y()(this,e),this.domains=U.a.domains,this.visibility=N.a.computed(function(){return t.domains.loading()?"visible":"hidden"}),this.domainForDeletion=N.a.observable(null).deleteAccessHelper(),this.onDomainListChangeRequest=D.a.bind(this.onDomainListChangeRequest,this),this.onDomainLoadRequest=D.a.bind(this.onDomainLoadRequest,this)}return e.prototype.createDomain=function(){Object(z.showScreenPopup)(n(176))},e.prototype.createDomainAlias=function(){Object(z.showScreenPopup)(n(190))},e.prototype.deleteDomain=function(e){this.domains.remove(e),q.a.domainDelete(this.onDomainListChangeRequest,e.name)},e.prototype.disableDomain=function(e){e.disabled(!e.disabled()),q.a.domainDisable(this.onDomainListChangeRequest,e.name,e.disabled())},e.prototype.onBuild=function(e){var t=this;e.on("click",".b-admin-domains-list-table .e-item .e-action",function(){var e=N.a.dataFor(this);e&&q.a.domain(t.onDomainLoadRequest,e.name)}),Object(X.a)().reloadDomainList()},e.prototype.onDomainLoadRequest=function(e,t){P.StorageResultType.Success===e&&t&&t.Result&&Object(z.showScreenPopup)(n(176),[t.Result])},e.prototype.onDomainListChangeRequest=function(){Object(X.a)().reloadDomainList()},e}(),Z=function(){function e(){y()(this,e),this.determineUserLanguage=M.a.determineUserLanguage,this.determineUserDomain=M.a.determineUserDomain,this.defaultDomain=N.a.observable(Object(L.settingsGet)("LoginDefaultDomain")).idleTrigger(),this.allowLanguagesOnLogin=M.a.allowLanguagesOnLogin,this.dummy=N.a.observable(!1)}return e.prototype.onBuild=function(){var e=this;D.a.delay(function(){var t=Object(k.settingsSaveHelperSimpleFunction)(e.defaultDomain.trigger,e);e.determineUserLanguage.subscribe(function(e){q.a.saveAdminConfig(null,{DetermineUserLanguage:Object(k.boolToAjax)(e)})}),e.determineUserDomain.subscribe(function(e){q.a.saveAdminConfig(null,{DetermineUserDomain:Object(k.boolToAjax)(e)})}),e.allowLanguagesOnLogin.subscribe(function(e){q.a.saveAdminConfig(null,{AllowLanguagesOnLogin:Object(k.boolToAjax)(e)})}),e.defaultDomain.subscribe(function(e){q.a.saveAdminConfig(t,{LoginDefaultDomain:Object(k.trim)(e)})})},50)},e}(),ee=n(18),te=n.n(ee),ne=(i=Object(z.command)(function(e){return""!==e.pdoDsn()&&""!==e.pdoUser()}),o=function(){function e(){var t=this;y()(this,e),this.defautOptionsAfterRender=k.defautOptionsAfterRender,this.enableContacts=N.a.observable(!!Object(L.settingsGet)("ContactsEnable")),this.contactsSync=N.a.observable(!!Object(L.settingsGet)("ContactsSync"));var n=[];Object(L.settingsGet)("SQLiteIsSupported")&&n.push("sqlite"),Object(L.settingsGet)("MySqlIsSupported")&&n.push("mysql"),Object(L.settingsGet)("PostgreSqlIsSupported")&&n.push("pgsql"),this.contactsSupported=00&&void 0!==arguments[0]?arguments[0]:null,t=null;t=n(188).default,Object(z.addSettingsViewModel)(J,"AdminSettingsGeneral","TABS_LABELS/LABEL_GENERAL_NAME","general",!0),Object(z.addSettingsViewModel)(Q,"AdminSettingsDomains","TABS_LABELS/LABEL_DOMAINS_NAME","domains"),Object(z.addSettingsViewModel)(Z,"AdminSettingsLogin","TABS_LABELS/LABEL_LOGIN_NAME","login"),t&&Object(z.addSettingsViewModel)(t,"AdminSettingsBranding","TABS_LABELS/LABEL_BRANDING_NAME","branding"),Object(z.addSettingsViewModel)(ne,"AdminSettingsContacts","TABS_LABELS/LABEL_CONTACTS_NAME","contacts"),Object(z.addSettingsViewModel)(ie,"AdminSettingsSecurity","TABS_LABELS/LABEL_SECURITY_NAME","security"),Object(z.addSettingsViewModel)(ae,"AdminSettingsSocial","TABS_LABELS/LABEL_INTEGRATION_NAME","integrations"),Object(z.addSettingsViewModel)(re,"AdminSettingsPlugins","TABS_LABELS/LABEL_PLUGINS_NAME","plugins"),Object(z.addSettingsViewModel)(se,"AdminSettingsPackages","TABS_LABELS/LABEL_PACKAGES_NAME","packages"),Object(z.addSettingsViewModel)(ce,"AdminSettingsAbout","TABS_LABELS/LABEL_ABOUT_NAME","about"),Object(K.g)(!0),e&&e()},t.prototype.onShow=function(){Object(X.a)().setWindowTitle("")},t}(W.a),ve=n(65),Se=(h=Object(z.view)({name:"View/Admin/Login",type:z.ViewType.Center,templateID:"AdminLogin"}),g=Object(z.command)(function(e){return!e.submitRequest()}),h((function(e,t,n,i,o){var a={};Object.keys(i).forEach(function(e){a[e]=i[e]}),a.enumerable=!!a.enumerable,a.configurable=!!a.configurable,("value"in a||a.initializer)&&(a.writable=!0),a=n.slice().reverse().reduce(function(n,i){return i(e,t,n)||n},a),o&&void 0!==a.initializer&&(a.value=a.initializer?a.initializer.call(o):void 0,a.initializer=void 0),void 0===a.initializer&&(Object.defineProperty(e,t,a),a=null)}((v=function(e){function t(){y()(this,t);var n=A()(this,e.call(this));return n.loginPowered=!!L.settingsGet("LoginPowered"),n.mobile=!!L.appSettingsGet("mobile"),n.mobileDevice=!!L.appSettingsGet("mobileDevice"),n.hideSubmitButton=!!L.appSettingsGet("hideSubmitButton"),n.login=N.a.observable(""),n.password=N.a.observable(""),n.loginError=N.a.observable(!1),n.passwordError=N.a.observable(!1),n.loginErrorAnimation=N.a.observable(!1).extend({falseTimeout:500}),n.passwordErrorAnimation=N.a.observable(!1).extend({falseTimeout:500}),n.loginFocus=N.a.observable(!1),n.formHidden=N.a.observable(!1),n.formError=N.a.computed(function(){return n.loginErrorAnimation()||n.passwordErrorAnimation()}),n.login.subscribe(function(){return n.loginError(!1)}),n.password.subscribe(function(){return n.passwordError(!1)}),n.loginError.subscribe(function(e){return n.loginErrorAnimation(!!e)}),n.passwordError.subscribe(function(e){n.passwordErrorAnimation(!!e)}),n.submitRequest=N.a.observable(!1),n.submitError=N.a.observable(""),n}return T()(t,e),t.prototype.submitCommand=function(){var e=this;return Object(k.triggerAutocompleteInputChange)(),this.loginError(!1),this.passwordError(!1),this.loginError(""===Object(k.trim)(this.login())),this.passwordError(""===Object(k.trim)(this.password())),!this.loginError()&&!this.passwordError()&&(this.submitRequest(!0),fe.$win.trigger("rl.tooltips.diactivate"),q.a.adminLogin(function(t,n){fe.$win.trigger("rl.tooltips.diactivate"),fe.$win.trigger("rl.tooltips.activate"),P.StorageResultType.Success===t&&n&&"AdminLogin"===n.Action?n.Result?Object(X.a)().loginAndLogoutReload(!0):n.ErrorCode&&(e.submitRequest(!1),e.submitError(Object(x.getNotification)(n.ErrorCode))):(e.submitRequest(!1),e.submitError(Object(x.getNotification)(P.Notification.UnknownError)))},this.login(),this.password()),!0)},t.prototype.onShow=function(){var e=this;Object(z.routeOff)(),D.a.delay(function(){e.loginFocus(!0)},P.Magics.Time100ms)},t.prototype.onHide=function(){this.loginFocus(!1)},t.prototype.onBuild=function(){Object(k.triggerAutocompleteInputChange)(!0)},t.prototype.submitForm=function(){this.submitCommand()},t}(me.a)).prototype,"submitCommand",[g],te()(v.prototype,"submitCommand"),v.prototype),b=v))||b),ye=function(e){function t(){return y()(this,t),A()(this,e.call(this,"login",[Se]))}return T()(t,e),t.prototype.onShow=function(){Object(X.a)().setWindowTitle("")},t}(ve.a),we=function(e){function t(){return y()(this,t),A()(this,e.call(this,q.a))}return T()(t,e),t.prototype.remote=function(){return q.a},t.prototype.reloadDomainList=function(){U.a.domains.loading(!0),q.a.domainList(function(e,t){U.a.domains.loading(!1),P.StorageResultType.Success===e&&t&&t.Result&&U.a.domains(D.a.map(t.Result,function(e,t){var n=e[0],i=e[1];return{name:t,disabled:N.a.observable(!n),alias:i,deleteAccess:N.a.observable(!1)}}))})},t.prototype.reloadPluginList=function(){H.plugins.loading(!0),q.a.pluginList(function(e,t){H.plugins.loading(!1),P.StorageResultType.Success===e&&t&&t.Result&&H.plugins(D.a.map(t.Result,function(e){return{name:e.Name,disabled:N.a.observable(!e.Enabled),configured:N.a.observable(!!e.Configured)}}))})},t.prototype.reloadPackagesList=function(){B.packages.loading(!0),B.packagesReal(!0),q.a.packagesList(function(e,t){if(B.packages.loading(!1),P.StorageResultType.Success===e&&t&&t.Result){B.packagesReal(!!t.Result.Real),B.packagesMainUpdatable(!!t.Result.MainUpdatable);var n=[],i={};D.a.each(B.packages(),function(e){e&&e.loading()&&(i[e.file]=e)}),Object(k.isArray)(t.Result.List)&&(n=D.a.compact(D.a.map(t.Result.List,function(e){return e?(e.loading=N.a.observable(!Object(k.isUnd)(i[e.file])),"core"!==e.type||e.canBeInstalled?e:null):null}))),B.packages(n)}else B.packagesReal(!1)})},t.prototype.updateCoreData=function(){V.coreUpdating(!0),q.a.updateCoreData(function(e,t){V.coreUpdating(!1),V.coreVersion(""),V.coreRemoteVersion(""),V.coreRemoteRelease(""),V.coreVersionCompare(-2),P.StorageResultType.Success===e&&t&&t.Result?(V.coreReal(!0),_.a.location.reload()):V.coreReal(!1)})},t.prototype.reloadCoreData=function(){V.coreChecking(!0),V.coreReal(!0),q.a.coreData(function(e,t){V.coreChecking(!1),P.StorageResultType.Success===e&&t&&t.Result?(V.coreReal(!!t.Result.Real),V.coreChannel(t.Result.Channel||"stable"),V.coreType(t.Result.Type||"stable"),V.coreUpdatable(!!t.Result.Updatable),V.coreAccess(!!t.Result.Access),V.coreWarning(!!t.Result.Warning),V.coreVersion(t.Result.Version||""),V.coreRemoteVersion(t.Result.RemoteVersion||""),V.coreRemoteRelease(t.Result.RemoteRelease||""),V.coreVersionCompare(Object(k.pInt)(t.Result.VersionCompare))):(V.coreReal(!1),V.coreChannel("stable"),V.coreType("stable"),V.coreWarning(!1),V.coreVersion(""),V.coreRemoteVersion(""),V.coreRemoteRelease(""),V.coreVersionCompare(-2))})},t.prototype.reloadLicensing=function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];G.licensingProcess(!0),G.licenseError(""),q.a.licensing(function(e,t){G.licensingProcess(!1),P.StorageResultType.Success===e&&t&&t.Result&&Object(k.isNormal)(t.Result.Expired)?(G.licenseValid(!0),G.licenseExpired(Object(k.pInt)(t.Result.Expired)),G.licenseError(""),G.licensing(!0),M.a.prem(!0)):t&&t.ErrorCode&&-10&&void 0!==arguments[0]?arguments[0]:null;R.a&&R.a.end(),e&&e()},t.prototype.bootstart=function(){e.prototype.bootstart.call(this),M.a.populate(),F.a.populate(),Object(z.hideLoading)(),L.appSettingsGet("allowAdminPanel")?L.settingsGet("Auth")?Object(z.startScreens)([be]):Object(z.startScreens)([ye]):(Object(z.routeOff)(),Object(z.setHash)(Object(I.w)(),!0),Object(z.routeOff)(),D.a.defer(function(){_.a.location.href="/"})),this.bootend()},t}(n(113).a);t.default=new we},,,,function(e,t,n){"use strict";function i(e,t,n,i,o){var a={};return Object.keys(i).forEach(function(e){a[e]=i[e]}),a.enumerable=!!a.enumerable,a.configurable=!!a.configurable,("value"in a||a.initializer)&&(a.writable=!0),a=n.slice().reverse().reduce(function(n,i){return i(e,t,n)||n},a),o&&void 0!==a.initializer&&(a.value=a.initializer?a.initializer.call(o):void 0,a.initializer=void 0),void 0===a.initializer&&(Object.defineProperty(e,t,a),a=null),a}n.r(t),n.d(t,"DomainPopupView",function(){return x}),n.d(t,"default",function(){return x});var o,a,r,s,c,l,u,d,p=n(18),f=n.n(p),m=n(8),h=n.n(m),g=n(12),b=n.n(g),v=n(11),S=n.n(v),y=n(4),w=n.n(y),A=n(1),O=n(0),T=n(23),C=n(6),_=n(2),E=n(10),D=n(48),N=n(21),j=n(37),R=n(9),I=n(24),x=(o=Object(R.popup)({name:"View/Popup/Domain",templateID:"PopupsDomain"}),a=Object(R.command)(function(e){return e.canBeSaved()}),r=Object(R.command)(function(e){return e.canBeTested()}),s=Object(R.command)(),c=Object(R.command)(),l=Object(R.command)(),o((i((d=function(e){function t(){h()(this,t);var n=b()(this,e.call(this));return n.edit=A.a.observable(!1),n.saving=A.a.observable(!1),n.savingError=A.a.observable(""),n.page=A.a.observable("main"),n.sieveSettings=A.a.observable(!1),n.testing=A.a.observable(!1),n.testingDone=A.a.observable(!1),n.testingImapError=A.a.observable(!1),n.testingSieveError=A.a.observable(!1),n.testingSmtpError=A.a.observable(!1),n.testingImapErrorDesc=A.a.observable(""),n.testingSieveErrorDesc=A.a.observable(""),n.testingSmtpErrorDesc=A.a.observable(""),n.testingImapError.subscribe(function(e){e||n.testingImapErrorDesc("")}),n.testingSieveError.subscribe(function(e){e||n.testingSieveErrorDesc("")}),n.testingSmtpError.subscribe(function(e){e||n.testingSmtpErrorDesc("")}),n.imapServerFocus=A.a.observable(!1),n.sieveServerFocus=A.a.observable(!1),n.smtpServerFocus=A.a.observable(!1),n.name=A.a.observable(""),n.name.focused=A.a.observable(!1),n.imapServer=A.a.observable(""),n.imapPort=A.a.observable(""+T.h),n.imapSecure=A.a.observable(O.ServerSecure.None),n.imapShortLogin=A.a.observable(!1),n.useSieve=A.a.observable(!1),n.sieveAllowRaw=A.a.observable(!1),n.sieveServer=A.a.observable(""),n.sievePort=A.a.observable(""+T.o),n.sieveSecure=A.a.observable(O.ServerSecure.None),n.smtpServer=A.a.observable(""),n.smtpPort=A.a.observable(""+T.p),n.smtpSecure=A.a.observable(O.ServerSecure.None),n.smtpShortLogin=A.a.observable(!1),n.smtpAuth=A.a.observable(!0),n.smtpPhpMail=A.a.observable(!1),n.whiteList=A.a.observable(""),n.aliasName=A.a.observable(""),n.enableSmartPorts=A.a.observable(!1),n.allowSieve=A.a.computed(function(){return D.a.filters()&&D.a.sieve()}),n.headerText=A.a.computed(function(){var e=n.name(),t=n.aliasName(),i="";return n.edit()?(i=Object(E.i18n)("POPUPS_DOMAIN/TITLE_EDIT_DOMAIN",{NAME:e}),t&&(i+=" ← "+t)):i=""===e?Object(E.i18n)("POPUPS_DOMAIN/TITLE_ADD_DOMAIN"):Object(E.i18n)("POPUPS_DOMAIN/TITLE_ADD_DOMAIN_WITH_NAME",{NAME:e}),i}),n.domainDesc=A.a.computed(function(){var e=n.name();return!n.edit()&&e?Object(E.i18n)("POPUPS_DOMAIN/NEW_DOMAIN_DESC",{NAME:"*@"+e}):""}),n.domainIsComputed=A.a.computed(function(){var e=n.smtpPhpMail(),t=n.allowSieve(),i=n.useSieve();return""!==n.name()&&""!==n.imapServer()&&""!==n.imapPort()&&(!t||!i||""!==n.sieveServer()&&""!==n.sievePort())&&(""!==n.smtpServer()&&""!==n.smtpPort()||e)}),n.canBeTested=A.a.computed(function(){return!n.testing()&&n.domainIsComputed()}),n.canBeSaved=A.a.computed(function(){return!n.saving()&&n.domainIsComputed()}),n.page.subscribe(function(){n.sieveSettings(!1)}),n.imapServerFocus.subscribe(function(e){e&&""!==n.name()&&""===n.imapServer()&&n.imapServer(n.name().replace(/[.]?[*][.]?/g,""))}),n.sieveServerFocus.subscribe(function(e){e&&""!==n.imapServer()&&""===n.sieveServer()&&n.sieveServer(n.imapServer())}),n.smtpServerFocus.subscribe(function(e){e&&""!==n.imapServer()&&""===n.smtpServer()&&n.smtpServer(n.imapServer().replace(/imap/gi,"smtp"))}),n.imapSecure.subscribe(function(e){if(n.enableSmartPorts()){var t=Object(_.pInt)(n.imapPort());switch(Object(_.pString)(e)){case"0":case"2":O.Ports.ImapSsl===t&&n.imapPort(Object(_.pString)(O.Ports.Imap));break;case"1":O.Ports.Imap===t&&n.imapPort(Object(_.pString)(O.Ports.ImapSsl))}}}),n.smtpSecure.subscribe(function(e){if(n.enableSmartPorts()){var t=Object(_.pInt)(n.smtpPort());switch(Object(_.pString)(e)){case"0":O.Ports.SmtpSsl!==t&&O.Ports.SmtpStartTls!==t||n.smtpPort(Object(_.pString)(O.Ports.Smtp));break;case"1":O.Ports.Smtp!==t&&O.Ports.SmtpStartTls!==t||n.smtpPort(Object(_.pString)(O.Ports.SmtpSsl));break;case"2":O.Ports.Smtp!==t&&O.Ports.SmtpSsl!==t||n.smtpPort(Object(_.pString)(O.Ports.SmtpStartTls))}}}),n}return S()(t,e),t.prototype.createOrAddCommand=function(){this.saving(!0),N.a.createOrUpdateDomain(w.a.bind(this.onDomainCreateOrSaveResponse,this),!this.edit(),this.name(),this.imapServer(),Object(_.pInt)(this.imapPort()),this.imapSecure(),this.imapShortLogin(),this.useSieve(),this.sieveAllowRaw(),this.sieveServer(),Object(_.pInt)(this.sievePort()),this.sieveSecure(),this.smtpServer(),Object(_.pInt)(this.smtpPort()),this.smtpSecure(),this.smtpShortLogin(),this.smtpAuth(),this.smtpPhpMail(),this.whiteList())},t.prototype.testConnectionCommand=function(){this.page("main"),this.testingDone(!1),this.testingImapError(!1),this.testingSieveError(!1),this.testingSmtpError(!1),this.testing(!0),N.a.testConnectionForDomain(w.a.bind(this.onTestConnectionResponse,this),this.name(),this.imapServer(),Object(_.pInt)(this.imapPort()),this.imapSecure(),this.useSieve(),this.sieveServer(),Object(_.pInt)(this.sievePort()),this.sieveSecure(),this.smtpServer(),Object(_.pInt)(this.smtpPort()),this.smtpSecure(),this.smtpAuth(),this.smtpPhpMail())},t.prototype.whiteListCommand=function(){this.page("white-list")},t.prototype.backCommand=function(){this.page("main")},t.prototype.sieveCommand=function(){this.sieveSettings(!this.sieveSettings()),this.clearTesting()},t.prototype.onTestConnectionResponse=function(e,t){if(this.testing(!1),O.StorageResultType.Success===e&&t.Result){var n=!1,i=!1;this.testingDone(!0),this.testingImapError(!0!==t.Result.Imap),this.testingSieveError(!0!==t.Result.Sieve),this.testingSmtpError(!0!==t.Result.Smtp),this.testingImapError()&&t.Result.Imap&&(n=!0,this.testingImapErrorDesc(""),this.testingImapErrorDesc(t.Result.Imap)),this.testingSieveError()&&t.Result.Sieve&&(i=!0,this.testingSieveErrorDesc(""),this.testingSieveErrorDesc(t.Result.Sieve)),this.testingSmtpError()&&t.Result.Smtp&&(this.testingSmtpErrorDesc(""),this.testingSmtpErrorDesc(t.Result.Smtp)),this.sieveSettings()?!i&&n&&this.sieveSettings(!1):i&&!n&&this.sieveSettings(!0)}else this.testingImapError(!0),this.testingSieveError(!0),this.testingSmtpError(!0),this.sieveSettings(!1)},t.prototype.onDomainCreateOrSaveResponse=function(e,t){this.saving(!1),O.StorageResultType.Success===e&&t?t.Result?(Object(j.a)().reloadDomainList(),this.closeCommand()):O.Notification.DomainAlreadyExists===t.ErrorCode&&this.savingError(Object(E.i18n)("ERRORS/DOMAIN_ALREADY_EXISTS")):this.savingError(Object(E.i18n)("ERRORS/UNKNOWN_ERROR"))},t.prototype.clearTesting=function(){this.testing(!1),this.testingDone(!1),this.testingImapError(!1),this.testingSieveError(!1),this.testingSmtpError(!1)},t.prototype.onHide=function(){this.page("main"),this.sieveSettings(!1)},t.prototype.onShow=function(e){this.saving(!1),this.page("main"),this.sieveSettings(!1),this.clearTesting(),this.clearForm(),e&&(this.enableSmartPorts(!1),this.edit(!0),this.name(Object(_.trim)(e.Name)),this.imapServer(Object(_.trim)(e.IncHost)),this.imapPort(""+Object(_.pInt)(e.IncPort)),this.imapSecure(Object(_.trim)(e.IncSecure)),this.imapShortLogin(!!e.IncShortLogin),this.useSieve(!!e.UseSieve),this.sieveAllowRaw(!!e.SieveAllowRaw),this.sieveServer(Object(_.trim)(e.SieveHost)),this.sievePort(""+Object(_.pInt)(e.SievePort)),this.sieveSecure(Object(_.trim)(e.SieveSecure)),this.smtpServer(Object(_.trim)(e.OutHost)),this.smtpPort(""+Object(_.pInt)(e.OutPort)),this.smtpSecure(Object(_.trim)(e.OutSecure)),this.smtpShortLogin(!!e.OutShortLogin),this.smtpAuth(!!e.OutAuth),this.smtpPhpMail(!!e.OutUsePhpMail),this.whiteList(Object(_.trim)(e.WhiteList)),this.aliasName(Object(_.trim)(e.AliasName)),this.enableSmartPorts(!0))},t.prototype.onShowWithDelay=function(){""!==this.name()||C.bMobileDevice||this.name.focused(!0)},t.prototype.clearForm=function(){this.edit(!1),this.page("main"),this.sieveSettings(!1),this.enableSmartPorts(!1),this.savingError(""),this.name(""),this.name.focused(!1),this.imapServer(""),this.imapPort(""+T.h),this.imapSecure(O.ServerSecure.None),this.imapShortLogin(!1),this.useSieve(!1),this.sieveAllowRaw(!1),this.sieveServer(""),this.sievePort(""+T.o),this.sieveSecure(O.ServerSecure.None),this.smtpServer(""),this.smtpPort(""+T.p),this.smtpSecure(O.ServerSecure.None),this.smtpShortLogin(!1),this.smtpAuth(!0),this.smtpPhpMail(!1),this.whiteList(""),this.aliasName(""),this.enableSmartPorts(!0)},t}(I.a)).prototype,"createOrAddCommand",[a],f()(d.prototype,"createOrAddCommand"),d.prototype),i(d.prototype,"testConnectionCommand",[r],f()(d.prototype,"testConnectionCommand"),d.prototype),i(d.prototype,"whiteListCommand",[s],f()(d.prototype,"whiteListCommand"),d.prototype),i(d.prototype,"backCommand",[c],f()(d.prototype,"backCommand"),d.prototype),i(d.prototype,"sieveCommand",[l],f()(d.prototype,"sieveCommand"),d.prototype),u=d))||u)},,,,,,,,,,,,function(e,t,n){"use strict";n.r(t),n.d(t,"BrandingAdminSettings",function(){return m}),n.d(t,"default",function(){return m});var i=n(8),o=n.n(i),a=n(4),r=n.n(a),s=n(1),c=n(0),l=n(2),u=n(10),d=n(21),p=n(38),f=n(5),m=function(){function e(){o()(this,e),this.capa=p.a.prem,this.title=s.a.observable(Object(f.settingsGet)("Title")).idleTrigger(),this.loadingDesc=s.a.observable(Object(f.settingsGet)("LoadingDescription")).idleTrigger(),this.faviconUrl=s.a.observable(Object(f.settingsGet)("FaviconUrl")).idleTrigger(),this.loginLogo=s.a.observable(Object(f.settingsGet)("LoginLogo")||"").idleTrigger(),this.loginBackground=s.a.observable(Object(f.settingsGet)("LoginBackground")||"").idleTrigger(),this.userLogo=s.a.observable(Object(f.settingsGet)("UserLogo")||"").idleTrigger(),this.userLogoMessage=s.a.observable(Object(f.settingsGet)("UserLogoMessage")||"").idleTrigger(),this.userIframeMessage=s.a.observable(Object(f.settingsGet)("UserIframeMessage")||"").idleTrigger(),this.userLogoTitle=s.a.observable(Object(f.settingsGet)("UserLogoTitle")||"").idleTrigger(),this.loginDescription=s.a.observable(Object(f.settingsGet)("LoginDescription")).idleTrigger(),this.loginCss=s.a.observable(Object(f.settingsGet)("LoginCss")).idleTrigger(),this.userCss=s.a.observable(Object(f.settingsGet)("UserCss")).idleTrigger(),this.welcomePageUrl=s.a.observable(Object(f.settingsGet)("WelcomePageUrl")).idleTrigger(),this.welcomePageDisplay=s.a.observable(Object(f.settingsGet)("WelcomePageDisplay")).idleTrigger(),this.welcomePageDisplay.options=s.a.computed(function(){return Object(u.trigger)(),[{optValue:"none",optText:Object(u.i18n)("TAB_BRANDING/OPTION_WELCOME_PAGE_DISPLAY_NONE")},{optValue:"once",optText:Object(u.i18n)("TAB_BRANDING/OPTION_WELCOME_PAGE_DISPLAY_ONCE")},{optValue:"always",optText:Object(u.i18n)("TAB_BRANDING/OPTION_WELCOME_PAGE_DISPLAY_ALWAYS")}]}),this.loginPowered=s.a.observable(!!Object(f.settingsGet)("LoginPowered")),this.community=!0}return e.prototype.onBuild=function(){var e=this;r.a.delay(function(){var t=Object(l.settingsSaveHelperSimpleFunction)(e.title.trigger,e),n=Object(l.settingsSaveHelperSimpleFunction)(e.loadingDesc.trigger,e),i=Object(l.settingsSaveHelperSimpleFunction)(e.faviconUrl.trigger,e);e.title.subscribe(function(e){d.a.saveAdminConfig(t,{Title:Object(l.trim)(e)})}),e.loadingDesc.subscribe(function(e){d.a.saveAdminConfig(n,{LoadingDescription:Object(l.trim)(e)})}),e.faviconUrl.subscribe(function(e){d.a.saveAdminConfig(i,{FaviconUrl:Object(l.trim)(e)})})},c.Magics.Time50ms)},e}()},function(e,t,n){"use strict";n.r(t),n.d(t,"PluginPopupView",function(){return I}),n.d(t,"default",function(){return I});var i,o,a,r,s,c,l,u,d,p,f=n(18),m=n.n(f),h=n(8),g=n.n(h),b=n(12),v=n.n(b),S=n(11),y=n.n(S),w=n(4),A=n.n(w),O=n(1),T=n(19),C=n.n(T),_=n(0),E=n(2),D=n(10),N=n(21),j=n(9),R=n(24),I=(i=Object(j.popup)({name:"View/Popup/Plugin",templateID:"PopupsPlugin"}),o=Object(j.command)(function(e){return e.hasConfiguration()}),i((r=function(e){function t(){g()(this,t);var n=v()(this,e.call(this));return n.onPluginSettingsUpdateResponse=A.a.bind(n.onPluginSettingsUpdateResponse,n),n.saveError=O.a.observable(""),n.name=O.a.observable(""),n.readme=O.a.observable(""),n.configures=O.a.observableArray([]),n.hasReadme=O.a.computed(function(){return""!==n.readme()}),n.hasConfiguration=O.a.computed(function(){return 0"+n.readme()+""}},n.bDisabeCloseOnEsc=!0,n.sDefaultKeyScope=_.KeyState.All,n.tryToClosePopup=A.a.debounce(A.a.bind(n.tryToClosePopup,n),_.Magics.Time200ms),n}return y()(t,e),t.prototype.saveCommand=function(){var e={};e.Name=this.name(),A.a.each(this.configures(),function(t){var n=t.value();!1!==n&&!0!==n||(n=n?"1":"0"),e["_"+t.Name]=n}),this.saveError(""),N.a.pluginSettingsUpdate(this.onPluginSettingsUpdateResponse,e)},t.prototype.onPluginSettingsUpdateResponse=function(e,t){_.StorageResultType.Success===e&&t&&t.Result?this.cancelCommand():(this.saveError(""),t&&t.ErrorCode?this.saveError(Object(D.getNotification)(t.ErrorCode)):this.saveError(Object(D.getNotification)(_.Notification.CantSavePluginSettings)))},t.prototype.onShow=function(e){if(this.name(),this.readme(),this.configures([]),e){this.name(e.Name),this.readme(e.Readme);var t=e.Config;Object(E.isNonEmptyArray)(t)&&this.configures(A.a.map(t,function(e){return{value:O.a.observable(e[0]),placeholder:O.a.observable(e[6]),Name:e[1],Type:e[2],Label:e[3],Default:e[4],Desc:e[5]}}))}},t.prototype.tryToClosePopup=function(){var e=this,t=n(99);Object(j.isPopupVisible)(t)||Object(j.showScreenPopup)(t,[Object(D.i18n)("POPUPS_ASK/DESC_WANT_CLOSE_THIS_WINDOW"),function(){e.modalVisibility()&&Object(E.delegateRun)(e,"cancelCommand")}])},t.prototype.onBuild=function(){var e=this;C()("esc",_.KeyState.All,function(){return e.modalVisibility()&&e.tryToClosePopup(),!1})},t}(R.a),s=r.prototype,c="saveCommand",l=[o],u=m()(r.prototype,"saveCommand"),d=r.prototype,p={},Object.keys(u).forEach(function(e){p[e]=u[e]}),p.enumerable=!!p.enumerable,p.configurable=!!p.configurable,("value"in p||p.initializer)&&(p.writable=!0),p=l.slice().reverse().reduce(function(e,t){return t(s,c,e)||e},p),d&&void 0!==p.initializer&&(p.value=p.initializer?p.initializer.call(d):void 0,p.initializer=void 0),void 0===p.initializer&&(Object.defineProperty(s,c,p),p=null),a=r))||a)},function(e,t,n){"use strict";n.r(t),n.d(t,"DomainAliasPopupView",function(){return I}),n.d(t,"default",function(){return I});var i,o,a,r,s,c,l,u,d,p,f=n(18),m=n.n(f),h=n(8),g=n.n(h),b=n(12),v=n.n(b),S=n(11),y=n.n(S),w=n(4),A=n.n(w),O=n(1),T=n(0),C=n(6),_=n(10),E=n(68),D=n(21),N=n(37),j=n(9),R=n(24),I=(i=Object(j.popup)({name:"View/Popup/DomainAlias",templateID:"PopupsDomainAlias"}),o=Object(j.command)(function(e){return e.canBeSaved()}),i((r=function(e){function t(){g()(this,t);var n=v()(this,e.call(this));return n.saving=O.a.observable(!1),n.savingError=O.a.observable(""),n.name=O.a.observable(""),n.name.focused=O.a.observable(!1),n.alias=O.a.observable(""),n.domains=E.a.domainsWithoutAliases,n.domainsOptions=O.a.computed(function(){return A.a.map(n.domains(),function(e){return{optValue:e.name,optText:e.name}})}),n.canBeSaved=O.a.computed(function(){return!n.saving()&&""!==n.name()&&""!==n.alias()}),n.onDomainAliasCreateOrSaveResponse=A.a.bind(n.onDomainAliasCreateOrSaveResponse,n),n}return y()(t,e),t.prototype.createCommand=function(){this.saving(!0),D.a.createDomainAlias(this.onDomainAliasCreateOrSaveResponse,this.name(),this.alias())},t.prototype.onDomainAliasCreateOrSaveResponse=function(e,t){this.saving(!1),T.StorageResultType.Success===e&&t?t.Result?(Object(N.a)().reloadDomainList(),this.closeCommand()):T.Notification.DomainAlreadyExists===t.ErrorCode&&this.savingError(Object(_.i18n)("ERRORS/DOMAIN_ALREADY_EXISTS")):this.savingError(Object(_.i18n)("ERRORS/UNKNOWN_ERROR"))},t.prototype.onShow=function(){this.clearForm()},t.prototype.onShowWithDelay=function(){""!==this.name()||C.bMobileDevice||this.name.focused(!0)},t.prototype.clearForm=function(){this.saving(!1),this.savingError(""),this.name(""),this.name.focused(!1),this.alias("")},t}(R.a),s=r.prototype,c="createCommand",l=[o],u=m()(r.prototype,"createCommand"),d=r.prototype,p={},Object.keys(u).forEach(function(e){p[e]=u[e]}),p.enumerable=!!p.enumerable,p.configurable=!!p.configurable,("value"in p||p.initializer)&&(p.writable=!0),p=l.slice().reverse().reduce(function(e,t){return t(s,c,e)||e},p),d&&void 0!==p.initializer&&(p.value=p.initializer?p.initializer.call(d):void 0,p.initializer=void 0),void 0===p.initializer&&(Object.defineProperty(s,c,p),p=null),a=r))||a)},function(e,t,n){"use strict";n.r(t);var i=n(117),o=n(172);Object(i.a)(o.default)}]); diff --git a/rainloop/app/rainloop/v/1.12.0/static/js/min/app.min.js b/rainloop/app/rainloop/v/1.12.0/static/js/min/app.min.js deleted file mode 100644 index 80b03f4dc4c06f62ccb2899ec6470cdd3a334fa3..0000000000000000000000000000000000000000 --- a/rainloop/app/rainloop/v/1.12.0/static/js/min/app.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e){function t(o){if(n[o])return n[o].exports;var i=n[o]={i:o,l:!1,exports:{}};return e[o].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var n={};t.m=e,t.c=n,t.d=function(e,n,o){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:o})},t.r=function(e){Object.defineProperty(e,"__esModule",{value:!0})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="rainloop/v/0.0.0/static/js/min/",t(t.s=201)}([function(e,t,n){"use strict";n.r(t),n.d(t,"FileType",function(){return o}),n.d(t,"StorageResultType",function(){return i}),n.d(t,"Focused",function(){return a}),n.d(t,"State",function(){return r}),n.d(t,"StateType",function(){return s}),n.d(t,"Capa",function(){return c}),n.d(t,"KeyState",function(){return l}),n.d(t,"FolderType",function(){return u}),n.d(t,"ServerFolderType",function(){return d}),n.d(t,"LoginSignMeTypeAsString",function(){return p}),n.d(t,"LoginSignMeType",function(){return h}),n.d(t,"ComposeType",function(){return f}),n.d(t,"UploadErrorCode",function(){return m}),n.d(t,"SetSystemFoldersNotification",function(){return b}),n.d(t,"ClientSideKeyName",function(){return g}),n.d(t,"EventKeyCode",function(){return y}),n.d(t,"MessageSetAction",function(){return v}),n.d(t,"MessageSelectAction",function(){return S}),n.d(t,"DesktopNotification",function(){return O}),n.d(t,"MessagePriority",function(){return w}),n.d(t,"EditorDefaultType",function(){return T}),n.d(t,"ServerSecure",function(){return C}),n.d(t,"SearchDateType",function(){return A}),n.d(t,"SaveSettingsStep",function(){return E}),n.d(t,"Layout",function(){return F}),n.d(t,"FilterConditionField",function(){return j}),n.d(t,"FilterConditionType",function(){return N}),n.d(t,"FiltersAction",function(){return R}),n.d(t,"FilterRulesType",function(){return I}),n.d(t,"SignedVerifyStatus",function(){return L}),n.d(t,"ContactPropertyType",function(){return _}),n.d(t,"Magics",function(){return P}),n.d(t,"Ports",function(){return D}),n.d(t,"Notification",function(){return M});var o={Unknown:"unknown",Text:"text",Html:"html",Code:"code",Eml:"eml",WordText:"word-text",Pdf:"pdf",Image:"image",Audio:"audio",Video:"video",Sheet:"sheet",Presentation:"presentation",Certificate:"certificate",CertificateBin:"certificate-bin",Archive:"archive"},i={Success:"success",Abort:"abort",Error:"error",Unload:"unload"},a={None:"none",MessageList:"message-list",MessageView:"message-view",FolderList:"folder-list"},r={Empty:10,Login:20,Auth:30},s={Webmail:0,Admin:1},c={TwoFactor:"TWO_FACTOR",TwoFactorForce:"TWO_FACTOR_FORCE",OpenPGP:"OPEN_PGP",Prefetch:"PREFETCH",Gravatar:"GRAVATAR",Folders:"FOLDERS",Composer:"COMPOSER",Contacts:"CONTACTS",Reload:"RELOAD",Search:"SEARCH",SearchAdv:"SEARCH_ADV",MessageActions:"MESSAGE_ACTIONS",MessageListActions:"MESSAGELIST_ACTIONS",AttachmentsActions:"ATTACHMENTS_ACTIONS",DangerousActions:"DANGEROUS_ACTIONS",Settings:"SETTINGS",Help:"HELP",Themes:"THEMES",UserBackground:"USER_BACKGROUND",Sieve:"SIEVE",Filters:"FILTERS",AttachmentThumbnails:"ATTACHMENT_THUMBNAILS",Templates:"TEMPLATES",AutoLogout:"AUTOLOGOUT",AdditionalAccounts:"ADDITIONAL_ACCOUNTS",Identities:"IDENTITIES"},l={All:"all",None:"none",ContactList:"contact-list",MessageList:"message-list",FolderList:"folder-list",MessageView:"message-view",Compose:"compose",Settings:"settings",Menu:"menu",PopupComposeOpenPGP:"compose-open-pgp",PopupMessageOpenPGP:"message-open-pgp",PopupViewOpenPGP:"view-open-pgp",PopupKeyboardShortcutsHelp:"popup-keyboard-shortcuts-help",PopupAsk:"popup-ask"},u={Inbox:10,SentItems:11,Draft:12,Trash:13,Spam:14,Archive:15,NotSpam:80,User:99},d={USER:0,INBOX:1,SENT:2,DRAFTS:3,JUNK:4,TRASH:5,IMPORTANT:10,FLAGGED:11,ALL:12},p={DefaultOff:"defaultoff",DefaultOn:"defaulton",Unused:"unused"},h={DefaultOff:0,DefaultOn:1,Unused:2},f={Empty:"empty",Reply:"reply",ReplyAll:"replyall",Forward:"forward",ForwardAsAttachment:"forward-as-attachment",Draft:"draft",EditAsNew:"editasnew"},m={Normal:0,FileIsTooBig:1,FilePartiallyUploaded:2,FileNoUploaded:3,MissingTempFolder:4,FileOnSaveingError:5,FileType:98,Unknown:99},b={None:0,Sent:1,Draft:2,Spam:3,Trash:4,Archive:5},g={FoldersLashHash:0,MessagesInboxLastHash:1,MailBoxListSize:2,ExpandedFolders:3,FolderListSize:4,MessageListSize:5,LastReplyAction:6,LastSignMe:7,ComposeLastIdentityID:8,MessageHeaderFullInfo:9,MessageAttachmnetControls:10},y={Backspace:8,Tab:9,Enter:13,Esc:27,PageUp:33,PageDown:34,Left:37,Right:39,Up:38,Down:40,End:35,Home:36,Space:32,Insert:45,Delete:46,A:65,S:83},v={SetSeen:0,UnsetSeen:1,SetFlag:2,UnsetFlag:3},S={All:0,None:1,Invert:2,Unseen:3,Seen:4,Flagged:5,Unflagged:6},O={Allowed:0,NotAllowed:1,Denied:2,NotSupported:9},w={Low:5,Normal:3,High:1},T={Html:"Html",Plain:"Plain",HtmlForced:"HtmlForced",PlainForced:"PlainForced"},C={None:0,SSL:1,TLS:2},A={All:-1,Days3:3,Days7:7,Month:30},E={Animate:-2,Idle:-1,TrueResult:1,FalseResult:0},F={NoPreview:0,SidePreview:1,BottomPreview:2},j={From:"From",Recipient:"Recipient",Subject:"Subject",Header:"Header",Size:"Size"},N={Contains:"Contains",NotContains:"NotContains",EqualTo:"EqualTo",NotEqualTo:"NotEqualTo",Regex:"Regex",Over:"Over",Under:"Under"},R={None:"None",MoveTo:"MoveTo",Discard:"Discard",Vacation:"Vacation",Reject:"Reject",Forward:"Forward"},I={All:"All",Any:"Any"},L={UnknownPublicKeys:-4,UnknownPrivateKey:-3,Unverified:-2,Error:-1,None:0,Success:1},_={Unknown:0,FullName:10,FirstName:15,LastName:16,MiddleName:16,Nick:18,NamePrefix:20,NameSuffix:21,Email:30,Phone:31,Web:32,Birthday:40,Facebook:90,Skype:91,GitHub:92,Note:110,Custom:250},P={EventWhichMouseMiddle:3,ifvisibleIdle10s:10,BitLength2048:2048,BitLength1024:1024,Size350px:350,Size50px:50,Size20px:20,Size1px:1,Time30mInMin:30,Time60m:36e5,Time30m:18e5,Time20m:12e5,Time15m:9e5,Time10m:6e5,Time5m:3e5,Time3m:18e4,Time2m:12e4,Time1m:6e4,Time30s:3e4,Time10s:1e4,Time7s:7e3,Time5s:5e3,Time3s:3e3,Time1s:1e3,Time500ms:500,Time350ms:350,Time250ms:250,Time200ms:200,Time100ms:100,Time50ms:50,Time20ms:20,Time10ms:10,Time1ms:1},D={Imap:143,ImapSsl:993,Smtp:25,SmtpSsl:465,SmtpStartTls:587},M={InvalidToken:101,AuthError:102,AccessError:103,ConnectionError:104,CaptchaError:105,SocialFacebookLoginAccessDisable:106,SocialTwitterLoginAccessDisable:107,SocialGoogleLoginAccessDisable:108,DomainNotAllowed:109,AccountNotAllowed:110,AccountTwoFactorAuthRequired:120,AccountTwoFactorAuthError:121,CouldNotSaveNewPassword:130,CurrentPasswordIncorrect:131,NewPasswordShort:132,NewPasswordWeak:133,NewPasswordForbidden:134,ContactsSyncError:140,CantGetMessageList:201,CantGetMessage:202,CantDeleteMessage:203,CantMoveMessage:204,CantCopyMessage:205,CantSaveMessage:301,CantSendMessage:302,InvalidRecipients:303,CantSaveFilters:351,CantGetFilters:352,FiltersAreNotCorrect:355,CantCreateFolder:400,CantRenameFolder:401,CantDeleteFolder:402,CantSubscribeFolder:403,CantUnsubscribeFolder:404,CantDeleteNonEmptyFolder:405,CantSaveSettings:501,CantSavePluginSettings:502,DomainAlreadyExists:601,CantInstallPackage:701,CantDeletePackage:702,InvalidPluginPackage:703,UnsupportedPluginPackage:704,LicensingServerIsUnavailable:710,LicensingExpired:711,LicensingBanned:712,DemoSendMessageError:750,DemoAccountError:751,AccountAlreadyExists:801,AccountDoesNotExist:802,MailServerError:901,ClientViewError:902,InvalidInputArgument:903,AjaxFalse:950,AjaxAbort:951,AjaxParse:952,AjaxTimeout:953,UnknownNotification:999,UnknownError:999}},function(e,t,n){"use strict";var o=n(3),i=n.n(o),a=n(4),r=n.n(a),s=n(7),c=n.n(s),l=i.a.Opentip||{};l.styles=l.styles||{},l.styles.rainloop={extends:"standard",fixed:!0,target:!0,delay:.2,hideDelay:0,hideEffect:"fade",hideEffectDuration:.2,showEffect:"fade",showEffectDuration:.2,showOn:"mouseover click",removeElementsOnHide:!0,background:"#fff",shadow:!1,borderColor:"#999",borderRadius:2,borderWidth:1},l.styles.rainloopTip={extends:"rainloop",delay:.4,group:"rainloopTips"},l.styles.rainloopErrorTip={extends:"rainloop",className:"rainloopErrorTip"};var u=n(97),d=n.n(u),p=n(0),h=i.a.ko,f=c()(i.a);h.bindingHandlers.updateWidth={init:function(e,t){var n=c()(e),o=t(),a=function(){o(n.width()),i.a.setTimeout(function(){o(n.width())},p.Magics.Time500ms)};f.on("resize",a),a(),h.utils.domNodeDisposal.addDisposeCallback(e,function(){f.off("resize",a)})}},h.bindingHandlers.editor={init:function(e,t){var o=null,i=t(),a=n(95).default,r=function(){i&&i.__editor&&i.__editor.setHtmlOrPlain(i())},s=function(){i&&i.__editor&&i(i.__editor.getDataWithHtmlMark())};h.isObservable(i)&&a&&(o=new a(e,s,function(){i.__editor=o,r()},s),i.__fetchEditorValue=s,i.subscribe(r))}},h.bindingHandlers.json={init:function(e,t){c()(e).text(i.a.JSON.stringify(h.unwrap(t())))},update:function(e,t){c()(e).text(i.a.JSON.stringify(h.unwrap(t())))}},h.bindingHandlers.scrollerShadows={init:function(e){var t=c()(e),n=t.find("[data-scroller-shadows-content]")[0]||null,o=r.a.throttle(function(){t.toggleClass("scroller-shadow-top",8=n.left&&e.pageX<=n.left+t.width()){if(e.pageY>=o-100&&e.pageY<=o){var a=function(){t.scrollTop(t.scrollTop()+3),r.windowResize()};t.data("timerScroll",i.a.setInterval(a,10)),a()}if(e.pageY>=n.top&&e.pageY<=n.top+100){var s=function(){t.scrollTop(t.scrollTop()-3),r.windowResize()};t.data("timerScroll",i.a.setInterval(s,10)),s()}}})},u.stop=function(){c()(l).each(function(){var e=c()(this);i.a.clearInterval(e.data("timerScroll")),e.data("timerScroll",!1)})}),u.helper=function(e){return t()(e&&e.target?h.dataFor(e.target):null)},c()(e).draggable(u).on("mousedown.koDraggable",function(){r.removeInFocus()}),h.utils.domNodeDisposal.addDisposeCallback(e,function(){c()(e).off("mousedown.koDraggable").draggable("destroy")})}}},h.bindingHandlers.droppable={init:function(e,t,o){if(!n(6).bMobileDevice){var i=t(),a=o(),r=a&&a.droppableOver?a.droppableOver:null,s=a&&a.droppableOut?a.droppableOut:null,l={tolerance:"pointer",hoverClass:"droppableHover",drop:null,over:null,out:null};i&&(l.drop=function(e,t){i(e,t)},r&&(l.over=function(e,t){r(e,t)}),s&&(l.out=function(e,t){s(e,t)}),c()(e).droppable(l),h.utils.domNodeDisposal.addDisposeCallback(e,function(){c()(e).droppable("destroy")}))}}},h.bindingHandlers.nano={init:function(e){var t=n(6),o=n(5);t.bDisableNanoScroll||o.appSettingsGet("useNativeScrollbars")||c()(e).addClass("nano").nanoScroller({iOSNativeScrolling:!1,preventPageScrolling:!0})}},h.bindingHandlers.saveTrigger={init:function(e){var t=c()(e);t.data("save-trigger-type",t.is("input[type=text],input[type=email],input[type=password],select,textarea")?"input":"custom"),"custom"===t.data("save-trigger-type")?t.append('  ').addClass("settings-saved-trigger"):t.addClass("settings-saved-trigger-input")},update:function(e,t){var n=h.unwrap(t()),o=c()(e);if("custom"===o.data("save-trigger-type"))switch(n.toString()){case"1":o.find(".animated,.error").hide().removeClass("visible").end().find(".success").show().addClass("visible");break;case"0":o.find(".animated,.success").hide().removeClass("visible").end().find(".error").show().addClass("visible");break;case"-2":o.find(".error,.success").hide().removeClass("visible").end().find(".animated").show().addClass("visible");break;default:o.find(".animated").hide().end().find(".error,.success").removeClass("visible")}else switch(n.toString()){case"1":o.addClass("success").removeClass("error");break;case"0":o.addClass("error").removeClass("success");break;case"-2":break;default:o.removeClass("error success")}}},h.bindingHandlers.emailsTags={init:function(e,t,o){var i=n(2),a=n(44).default,s=c()(e),l=t(),u=o().autoCompleteSource||null,d=[",",";","\n"];s.inputosaurus({parseOnBlur:!0,allowDragAndDrop:!0,focusCallback:function(e){l&&l.focused&&l.focused(!!e)},inputDelimiters:d,autoCompleteSource:u,splitHook:function(e){var t=i.trim(e);return t&&-1=i&&(i=t),i===e()&&""+i!=""+n&&e(i+1),e(i)}});return i(e()),i},h.extenders.limitedList=function(e,t){var o=n(2),i=h.computed({read:e,write:function(n){var i=h.unwrap(e),a=h.unwrap(t);o.isNonEmptyArray(a)?-11&&void 0!==arguments[1])||arguments[1];return!!i(e)&&(t?/^[0-9]*$/.test(e.toString()):/^[1-9]+[0-9]*$/.test(e.toString()))}function r(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=i(e)&&""!==e?ce.a.parseInt(e,10):t;return ce.a.isNaN(n)?t:n}function s(e){return i(e)?""+e:""}function c(e){return!!e}function l(e){return e?"1":"0"}function u(e){return Te(e)&&00&&void 0!==arguments[0]?arguments[0]:32,t="0123456789abcdefghijklmnopqrstuvwxyz",n=t.length;e=r(e);for(var o="";o.length1&&void 0!==arguments[1]?arguments[1]:100,n="",o="",i=e,a=0,r=0;i.length>t;)a=(o=i.substring(0,t)).lastIndexOf(" "),-1!==(r=o.lastIndexOf("\n"))&&(a=r),-1===a&&(a=t),n+=o.substring(0,a)+"\n",i=i.substring(a+1);return n+i}function v(){try{if(ce.a.document.activeElement)return Ee(ce.a.document.activeElement.__inFocusCache)&&(ce.a.document.activeElement.__inFocusCache=ue()(ce.a.document.activeElement).is("input,textarea,iframe,.cke_editable")),!!ce.a.document.activeElement.__inFocusCache}catch(e){}return!1}function S(e){if(ce.a.document&&ce.a.document.activeElement&&ce.a.document.activeElement.blur)try{var t=ue()(ce.a.document.activeElement);t&&t.is("input,textarea")?ce.a.document.activeElement.blur():e&&ce.a.document.activeElement.blur()}catch(e){}}function O(){try{if(ce.a&&ce.a.getSelection){var e=ce.a.getSelection();e&&e.removeAllRanges&&e.removeAllRanges()}else ce.a.document&&ce.a.document.selection&&ce.a.document.selection.empty&&ce.a.document.selection.empty()}catch(e){}}function w(e,t){e=Oe(e.toUpperCase()),t=Oe(t.replace(/[\s]+/g," "));var n=!1,o="RE"===e,i="FWD"===e,a=[],r=!i;return""!==t&&pe.a.each(t.split(":"),function(e){var t=Oe(e);n||!/^(RE|FWD)$/i.test(t)&&!/^(RE|FWD)[\[\(][\d]+[\]\)]$/i.test(t)?(a.push(e),n=!0):(o||(o=!!/^RE/i.test(t)),i||(i=!!/^FWD/i.test(t)))}),r?o=!1:i=!1,Oe((r?"Re: ":"Fwd: ")+(o?"Re: ":"")+(i?"Fwd: ":"")+Oe(a.join(":")))}function T(e,t){return ce.a.Math.round(e*ce.a.Math.pow(10,t))/ce.a.Math.pow(10,t)}function C(e){switch(e=r(e),!0){case 1073741824<=e:return T(e/1073741824,1)+"GB";case 1048576<=e:return T(e/1048576,1)+"MB";case 1024<=e:return T(e/1024,0)+"KB"}return e+"B"}function A(e){ce.a.console&&ce.a.console.log&&ce.a.console.log(e)}function E(e,t,n){var o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:0;e&&e[t]&&(o=r(o),n=Te(n)?n:[],0>=o?e[t].apply(e,n):pe.a.delay(function(){e[t].apply(e,n)},o))}function F(e){if((e=e||ce.a.event)&&e.ctrlKey&&!e.shiftKey&&!e.altKey){var t=e.keyCode||e.which;if(t===ge.EventKeyCode.S)return void e.preventDefault();if(t===ge.EventKeyCode.A){var n=e.target||e.srcElement;if(n&&("true"==""+n.contentEditable||n.tagName&&n.tagName.match(/INPUT|TEXTAREA/i)))return;ce.a.getSelection?ce.a.getSelection().removeAllRanges():ce.a.document.selection&&ce.a.document.selection.clear&&ce.a.document.selection.clear(),e.preventDefault()}}}function j(e,t){var n=!(arguments.length>2&&void 0!==arguments[2])||arguments[2],o=null;return(o=t?function(){for(var n=arguments.length,i=Array(n),a=0;a1&&void 0!==arguments[1]&&arguments[1];return n(10).i18n("LANGS_NAMES"+(!0===t?"_EN":"")+"/LANG_"+e.toUpperCase().replace(/[^a-zA-Z0-9]+/g,"_"),null,e)}function _(){return ue()('
 
').appendTo("#rl-hidden")}function P(e,t){t&&!Ee(t.disabled)&&e&&ue()(e).toggleClass("disabled",t.disabled).prop("disabled",t.disabled)}function D(e){e.find("blockquote.rl-bq-switcher").removeClass("rl-bq-switcher hidden-bq"),e.find(".rlBlockquoteSwitcher").off(".rlBlockquoteSwitcher").remove(),e.find("[data-html-editor-font-wrapper]").removeAttr("data-html-editor-font-wrapper")}function M(e,t,o,i){var a=e.title,r=e.subject,s=e.date,c=e.fromCreds,l=e.toCreds,u=e.toLabel,d=e.ccClass,p=e.ccCreds,h=e.ccLabel,f=ce.a.open(""),m=f.document,b=t.clone(),y=o?"html":"plain";D(b);var v=b?b.html():"";m.write(n(170).replace("{{title}}",g(a)).replace("{{subject}}",g(r)).replace("{{date}}",g(s)).replace("{{fromCreds}}",g(c)).replace("{{toCreds}}",g(l)).replace("{{toLabel}}",g(u)).replace("{{ccClass}}",g(d)).replace("{{ccCreds}}",g(p)).replace("{{ccLabel}}",g(h)).replace("{{bodyClass}}",y).replace("{{html}}",v)),m.close(),i&&ce.a.setTimeout(function(){return f.print()},100)}function k(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:1e3;return o=r(o),function(i,a,r,s,c){t.call(n,a&&a.Result?ge.SaveSettingsStep.TrueResult:ge.SaveSettingsStep.FalseResult),e&&e.call(n,i,a,r,s,c),pe.a.delay(function(){t.call(n,ge.SaveSettingsStep.Idle)},o)}}function x(e,t){return k(null,e,t,1e3)}function U(e,t,n,o){return function(i){if(e){switch(n){case"bool":case"boolean":i=i?"1":"0";break;case"int":case"integer":case"number":i=r(i);break;case"trim":i=Oe(i);break;default:i=s(i)}var a={};a[t]=i,e.saveAdminConfig?e.saveAdminConfig(o||null,a):e.saveSettings&&e.saveSettings(o||null,a)}}}function H(e){return me.a?me.a.link(e,{newWindow:!0,stripPrefix:!1,urls:!0,email:!0,mention:!1,phone:!1,hashtag:!1,replaceFn:function(e){return!(e&&"url"===e.getType()&&e.matchedText&&0!==e.matchedText.indexOf("http"))}}):e}function B(e){var t,n=0,o=0,i=0,a=0,r=0,s="";for(s=e.replace(/]*><\/p>/gi,"").replace(/]*>([\s\S\r\n\t]*)<\/pre>/gim,function(){for(var e=arguments.length,t=Array(e),n=0;n").replace(/[\r]/gm,""):""}).replace(/[\s]+/gm," ").replace(/((?:href|data)\s?=\s?)("[^"]+?"|'[^']+?')/gim,function(){for(var e=arguments.length,t=Array(e),n=0;n]*>/gim,"\n").replace(/<\/h[\d]>/gi,"\n").replace(/<\/p>/gi,"\n\n").replace(/]*>/gim,"\n").replace(/<\/ul>/gi,"\n").replace(/]*>/gim," * ").replace(/<\/li>/gi,"\n").replace(/<\/td>/gi,"\n").replace(/<\/tr>/gi,"\n").replace(/]*>/gim,"\n_______________________________\n\n").replace(/]*>([\s\S\r\n]*)<\/div>/gim,function e(){for(var t=arguments.length,n=Array(t),o=0;o]*>([\s\S\r\n]*)<\/div>/gim,e),i="\n"+Oe(i)+"\n"),i}return""}).replace(/]*>/gim,"\n__bq__start__\n").replace(/<\/blockquote>/gim,"\n__bq__end__\n").replace(/]*>([\s\S\r\n]*?)<\/a>/gim,function(){for(var e=arguments.length,t=Array(e),n=0;n/gi,"\n").replace(/ /gi," ").replace(/"/gi,'"').replace(/<[^>]*>/gm,""),s=y(s=(s=be.$div.html(s).text()).replace(/\n[ \t]+/gm,"\n").replace(/[\n]{3,}/gm,"\n\n").replace(/>/gi,">").replace(/</gi,"<").replace(/&/gi,"&")),n=0,o=800;0 "+Oe(t).replace(/\n/gm,"\n> ")).replace(/(^|\n)([> ]+)/gm,function(){for(var e=arguments.length,t=Array(e),n=0;n1&&void 0!==arguments[1]&&arguments[1],n=!1,o=!0,i=!0,a=[],r="",s=0,c=(e=(e=e.toString().replace(/\r/g,"")).replace(/^>[> ]>+/gm,function(e){var t=e[0];return t?t.replace(/[ ]+/g,""):t})).split("\n");do{for(o=!1,a=[],s=0;s"===(r=c[s]).substr(0,1))&&!n?(o=!0,n=!0,a.push("~~~blockquote~~~"),a.push(r.substr(1))):!i&&n?""!==r?(n=!1,a.push("~~~/blockquote~~~"),a.push(r)):a.push(r):i&&n?a.push(r.substr(1)):a.push(r);n&&(n=!1,a.push("~~~/blockquote~~~")),c=a}while(o);return e=(e=c.join("\n")).replace(/&/g,"&").replace(/>/g,">").replace(/").replace(/[\s]*~~~\/blockquote~~~/g,"").replace(/\n/g,"
"),t?H(e):e}function K(e,t,n,o,a,r,s,c,l,u){var d=null,p=!1,h=0,f=0,m=[];for(u=!Ee(u)&&!!u,l=i(l)?l:00&&void 0!==arguments[0]&&arguments[0]?pe.a.delay(e,100):e()}function q(e){ke[e]||(ke[e]=ue()('script[type="application/json"][data-configuration="'+e+'"]'));try{return JSON.parse(ke[e].text())}catch(e){}return{}}function W(e,t){var n=t||e;n&&"function"==typeof n.dispose&&n.dispose()}function Y(e){e&&(Te(e.disposables)&&pe.a.each(e.disposables,W),he.a.utils.objectForEach(e,W))}function $(e){e&&(Te(e)?pe.a.each(e,function(e){$(e)}):e&&e.onDestroy&&e.onDestroy())}function J(e,t){return!(!e||!e[0]||(e[0].styleSheet&&!Ee(e[0].styleSheet.cssText)?e[0].styleSheet.cssText=t:e.text(t),0))}function X(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:Re,n=ue()("#app-theme-link"),o=function(){xe=ce.a.setTimeout(function(){return t(ge.SaveSettingsStep.Idle)},1e3),Ue=null},i=ue()("#app-theme-style"),a=n.attr("href");a||(a=i.attr("data-href")),a&&("Json/"!==(a=(a=(a=a.toString().replace(/\/-\/[^\/]+\/\-\//,"/-/"+e+"/-/")).replace(/\/Css\/[^\/]+\/User\//,"/Css/0/User/")).replace(/\/Hash\/[^\/]+\//,"/Hash/-/")).substring(a.length-5,a.length)&&(a+="Json/"),ce.a.clearTimeout(xe),t(ge.SaveSettingsStep.Animate),Ue&&Ue.abort&&Ue.abort(),Ue=ue.a.ajax({url:a,dataType:"json"}).then(function(e){e&&Te(e)&&2===e.length&&(!n||!n[0]||i&&i[0]||(i=ue()(''),n.after(i),n.remove()),i&&i[0]&&J(i,e[1])&&i.attr("data-href",a).attr("data-theme",e[0]),t(ge.SaveSettingsStep.TrueResult))}).then(o,o))}function Z(e,t){return function(){var n=e(),o=t(),i=[],a=function(e){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"",a={current:e===n,name:""===o?e.toString():o.toString(),custom:""!==o,title:""===o?"":e.toString(),value:e.toString()};t?i.push(a):i.unshift(a)},r=0,s=0,c=2;if(1=n||o-2<=n)&&(c+=2),a(n),r=n,s=n);0=s)a(s,!0),c-=1;else if(0>=r)break;3===r?a(2,!1):3s&&a(Math.round((o+s)/2),!0,"..."),1s&&a(o,!0)}return i}}function Q(e){var t=(e=Oe(e).toLowerCase()).split(".").pop();return t===e?"":t}function ee(e){var t,n="application/octet-stream";return"winmail.dat"===(e=Oe(e).toLowerCase())?"application/ms-tnef":((t=Q(e))&&0this.height?[this.width-this.height,0]:[0,this.height-this.width],i.fillStyle="#fff",i.fillRect(0,0,t,t),i.drawImage(this,e[0]/2,e[1]/2,this.width-e[0],this.height-e[1],0,0,t,t),n(o.toDataURL("image/jpeg"))},o.src=e}function ie(e,t){if(e&&"mailto:"===e.toString().substr(0,7).toLowerCase()){if(!t)return!0;var o,i=[],a=null,r=null,c=(e=e.toString().substr(7)).replace(/\?.+$/,""),l=e.replace(/^[^\?]*\?/,""),u=n(44).default;return o=m(l),Ee(o.to)?i=u.parseEmailLine(c):(i=u.parseEmailLine(p(c+","+o.to)),i=pe.a.values(i.reduce(function(e,t){return t&&(e[t.email]&&e[t.email].name||(e[t.email]=t)),e},{}))),Ee(o.cc)||(a=u.parseEmailLine(p(o.cc))),Ee(o.bcc)||(r=u.parseEmailLine(p(o.bcc))),n(9).showScreenPopup(t,[ge.ComposeType.Empty,null,i,a,r,Ee(o.subject)?null:s(p(o.subject)),Ee(o.body)?null:G(s(p(o.body)))]),!0}return!1}function ae(e){ue()(function(){return e()})}function re(){He()}n.r(t);var se=n(3),ce=n.n(se),le=n(7),ue=n.n(le),de=n(4),pe=n.n(de),he=n(1),fe=n(96),me=n.n(fe),be=n(6),ge=n(0),ye={eml:"message/rfc822",mime:"message/rfc822",txt:"text/plain",text:"text/plain",def:"text/plain",list:"text/plain",in:"text/plain",ini:"text/plain",log:"text/plain",sql:"text/plain",cfg:"text/plain",conf:"text/plain",asc:"text/plain",rtx:"text/richtext",vcard:"text/vcard",vcf:"text/vcard",htm:"text/html",html:"text/html",csv:"text/csv",ics:"text/calendar",ifb:"text/calendar",xml:"text/xml",json:"application/json",swf:"application/x-shockwave-flash",hlp:"application/winhlp",wgt:"application/widget",chm:"application/vnd.ms-htmlhelp",p10:"application/pkcs10",p7c:"application/pkcs7-mime",p7m:"application/pkcs7-mime",p7s:"application/pkcs7-signature",torrent:"application/x-bittorrent",js:"application/javascript",pl:"text/perl",css:"text/css",asp:"text/asp",php:"application/x-httpd-php",php3:"application/x-httpd-php",php4:"application/x-httpd-php",php5:"application/x-httpd-php",phtml:"application/x-httpd-php",png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",jpe:"image/jpeg",jfif:"image/jpeg",gif:"image/gif",bmp:"image/bmp",cgm:"image/cgm",ief:"image/ief",ico:"image/x-icon",tif:"image/tiff",tiff:"image/tiff",svg:"image/svg+xml",svgz:"image/svg+xml",djv:"image/vnd.djvu",djvu:"image/vnd.djvu",webp:"image/webp",zip:"application/zip","7z":"application/x-7z-compressed",rar:"application/x-rar-compressed",exe:"application/x-msdownload",dll:"application/x-msdownload",scr:"application/x-msdownload",com:"application/x-msdownload",bat:"application/x-msdownload",msi:"application/x-msdownload",cab:"application/vnd.ms-cab-compressed",gz:"application/x-gzip",tgz:"application/x-gzip",bz:"application/x-bzip",bz2:"application/x-bzip2",deb:"application/x-debian-package",psf:"application/x-font-linux-psf",otf:"application/x-font-otf",pcf:"application/x-font-pcf",snf:"application/x-font-snf",ttf:"application/x-font-ttf",ttc:"application/x-font-ttf",mp3:"audio/mpeg",amr:"audio/amr",aac:"audio/x-aac",aif:"audio/x-aiff",aifc:"audio/x-aiff",aiff:"audio/x-aiff",wav:"audio/x-wav",wma:"audio/x-ms-wma",wax:"audio/x-ms-wax",midi:"audio/midi",mp4a:"audio/mp4",ogg:"audio/ogg",weba:"audio/webm",ra:"audio/x-pn-realaudio",ram:"audio/x-pn-realaudio",rmp:"audio/x-pn-realaudio-plugin",m3u:"audio/x-mpegurl",flv:"video/x-flv",qt:"video/quicktime",mov:"video/quicktime",wmv:"video/windows-media",avi:"video/x-msvideo",mpg:"video/mpeg",mpeg:"video/mpeg",mpe:"video/mpeg",m1v:"video/mpeg",m2v:"video/mpeg","3gp":"video/3gpp","3g2":"video/3gpp2",h261:"video/h261",h263:"video/h263",h264:"video/h264",jpgv:"video/jpgv",mp4:"video/mp4",mp4v:"video/mp4",mpg4:"video/mp4",ogv:"video/ogg",webm:"video/webm",m4v:"video/x-m4v",asf:"video/x-ms-asf",asx:"video/x-ms-asf",wm:"video/x-ms-wm",wmx:"video/x-ms-wmx",wvx:"video/x-ms-wvx",movie:"video/x-sgi-movie",pdf:"application/pdf",psd:"image/vnd.adobe.photoshop",ai:"application/postscript",eps:"application/postscript",ps:"application/postscript",doc:"application/msword",dot:"application/msword",rtf:"application/rtf",xls:"application/vnd.ms-excel",ppt:"application/vnd.ms-powerpoint",docx:"application/vnd.openxmlformats-officedocument.wordprocessingml.document",xlsx:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",dotx:"application/vnd.openxmlformats-officedocument.wordprocessingml.template",pptx:"application/vnd.openxmlformats-officedocument.presentationml.presentation",odt:"application/vnd.oasis.opendocument.text",ods:"application/vnd.oasis.opendocument.spreadsheet"},ve=n(59);n.d(t,"trim",function(){return Oe}),n.d(t,"inArray",function(){return we}),n.d(t,"isArray",function(){return Te}),n.d(t,"isObject",function(){return Ce}),n.d(t,"isFunc",function(){return Ae}),n.d(t,"isUnd",function(){return Ee}),n.d(t,"isNull",function(){return Fe}),n.d(t,"has",function(){return je}),n.d(t,"bind",function(){return Ne}),n.d(t,"noop",function(){return Re}),n.d(t,"noopTrue",function(){return Ie}),n.d(t,"noopFalse",function(){return Le}),n.d(t,"silentTryCatch",function(){return o}),n.d(t,"isNormal",function(){return i}),n.d(t,"isPosNumeric",function(){return a}),n.d(t,"pInt",function(){return r}),n.d(t,"pString",function(){return s}),n.d(t,"pBool",function(){return c}),n.d(t,"boolToAjax",function(){return l}),n.d(t,"isNonEmptyArray",function(){return u}),n.d(t,"encodeURIComponent",function(){return d}),n.d(t,"decodeURIComponent",function(){return p}),n.d(t,"decodeURI",function(){return h}),n.d(t,"encodeURI",function(){return f}),n.d(t,"simpleQueryParser",function(){return m}),n.d(t,"fakeMd5",function(){return b}),n.d(t,"encodeHtml",function(){return g}),n.d(t,"splitPlainText",function(){return y}),n.d(t,"timeOutAction",function(){return _e}),n.d(t,"timeOutActionSecond",function(){return Pe}),n.d(t,"inFocus",function(){return v}),n.d(t,"removeInFocus",function(){return S}),n.d(t,"removeSelection",function(){return O}),n.d(t,"replySubjectAdd",function(){return w}),n.d(t,"roundNumber",function(){return T}),n.d(t,"friendlySize",function(){return C}),n.d(t,"log",function(){return A}),n.d(t,"delegateRun",function(){return E}),n.d(t,"killCtrlACtrlS",function(){return F}),n.d(t,"createCommandLegacy",function(){return j}),n.d(t,"convertThemeName",function(){return De}),n.d(t,"quoteName",function(){return N}),n.d(t,"microtime",function(){return R}),n.d(t,"timestamp",function(){return I}),n.d(t,"convertLangName",function(){return L}),n.d(t,"draggablePlace",function(){return _}),n.d(t,"defautOptionsAfterRender",function(){return P}),n.d(t,"clearBqSwitcher",function(){return D}),n.d(t,"previewMessage",function(){return M}),n.d(t,"settingsSaveHelperFunction",function(){return k}),n.d(t,"settingsSaveHelperSimpleFunction",function(){return x}),n.d(t,"settingsSaveHelperSubscribeFunction",function(){return U}),n.d(t,"findEmailAndLinks",function(){return H}),n.d(t,"htmlToPlain",function(){return B}),n.d(t,"plainToHtml",function(){return G}),n.d(t,"folderListOptionsBuilder",function(){return K}),n.d(t,"selectElement",function(){return V}),n.d(t,"detectDropdownVisibility",function(){return Me}),n.d(t,"triggerAutocompleteInputChange",function(){return z}),n.d(t,"getConfigurationFromScriptTag",function(){return q}),n.d(t,"disposeOne",function(){return W}),n.d(t,"disposeObject",function(){return Y}),n.d(t,"delegateRunOnDestroy",function(){return $}),n.d(t,"appendStyles",function(){return J}),n.d(t,"changeTheme",function(){return X}),n.d(t,"computedPagenatorHelper",function(){return Z}),n.d(t,"getFileExtension",function(){return Q}),n.d(t,"mimeContentType",function(){return ee}),n.d(t,"isTransparent",function(){return te}),n.d(t,"getRealHeight",function(){return ne}),n.d(t,"resizeAndCrop",function(){return oe}),n.d(t,"mailToHelper",function(){return ie}),n.d(t,"domReady",function(){return ae}),n.d(t,"windowResize",function(){return He}),n.d(t,"windowResizeCallback",function(){return re}),n.d(t,"jassl",function(){return ve.a});var Se,Oe=ue.a.trim,we=ue.a.inArray,Te=pe.a.isArray,Ce=pe.a.isObject,Ae=pe.a.isFunction,Ee=pe.a.isUndefined,Fe=pe.a.isNull,je=pe.a.has,Ne=pe.a.bind,Re=function(){},Ie=function(){return!0},Le=function(){return!1},_e=(Se={},function(e,t,n){Se[e]=Ee(Se[e])?0:Se[e],ce.a.clearTimeout(Se[e]),Se[e]=ce.a.setTimeout(t,n)}),Pe=function(){var e={};return function(t,n,o){e[t]||(e[t]=ce.a.setTimeout(function(){n(),e[t]=0},o))}}(),De=pe.a.memoize(function(e){return"@custom"===e.substr(-7)&&(e=Oe(e.substring(0,e.length-7))),Oe(e.replace(/[^a-zA-Z0-9]+/g," ").replace(/([A-Z])/g," $1").replace(/[\s]+/g," "))});ce.a.rainloop_Utils_htmlToPlain=B,ce.a.rainloop_Utils_plainToHtml=G;var Me=pe.a.debounce(function(){Object(be.dropdownVisibility)(!!pe.a.find(be.data.aBootstrapDropdowns,function(e){return e.hasClass("open")}))},50),ke={},xe=0,Ue=null,He=pe.a.debounce(function(e){Ee(e)||Fe(e)?be.$win.resize():ce.a.setTimeout(function(){be.$win.resize()},e)},50),Be=ce.a.String.substr;"b"!=="ab".substr(-1)&&(Be=function(e,t,n){return t=0>t?e.length+t:t,e.substr(t,n)},ce.a.String.substr=Be)},function(e,t){e.exports=window},function(e,t){e.exports=window._},function(e,t,n){"use strict";function o(e){return Object(l.isUnd)(u[e])?null:u[e]}function i(e,t){u[e]=t}function a(e){return Object(l.isUnd)(d[e])?null:d[e]}function r(e){var t=o("Capa");return Object(l.isArray)(t)&&Object(l.isNormal)(e)&&-1"),y=c()("
");y.attr("area","hidden").css({position:"absolute",left:-5e3}).appendTo(b);var v=(new i.a.Date).getTime(),S=!0,O=d.a.observable(!1).extend({rateLimit:0}),w=d.a.observable(!0),T="navigator"in i.a&&"userAgent"in i.a.navigator&&i.a.navigator.userAgent.toLowerCase()||"",C=-11&&void 0!==arguments[1])||arguments[1];return Object(k.createCommandLegacy)(null,e,t)}function a(e,t,n,o){var i=arguments.length>4&&void 0!==arguments[4]&&arguments[4];e.__rlSettingsData={Label:n,Template:t,Route:o,IsDefault:!!i},M.VIEW_MODELS.settings.push(e)}function r(e){M.VIEW_MODELS["settings-removed"].push(e)}function s(e){M.VIEW_MODELS["settings-disabled"].push(e)}function c(){I.a.changed.active=!1}function l(){I.a.changed.active=!0}function u(e){return""===e||Object(k.isUnd)(H[e])?null:H[e]}function d(e){var t=null;return e&&(t=e,e.default&&(t=e.default)),t}function p(e){var t=d(e);t&&t.__vm&&t.__dom&&t.__vm.modalVisibility(!1)}function h(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;E.a.each(t.__names,function(o){Object(D.f)(e,[o,t.__vm,n])})}function f(e,t){if(e&&!e.__builded){var n=null,o=new e(t),a=e.__type||"",r=a?j()("#rl-content #rl-"+a.toLowerCase()):null;e.__builded=!0,e.__vm=o,o.onShowTrigger=N.a.observable(!1),o.onHideTrigger=N.a.observable(!1),o.viewModelName=e.__name,o.viewModelNames=e.__names,o.viewModelTemplateID=e.__templateID,o.viewModelPosition=e.__type,r&&1===r.length?((n=j()("
").addClass("rl-view-model").addClass("RL-"+o.viewModelTemplateID).hide()).appendTo(r),o.viewModelDom=n,e.__dom=n,B.Popup===a&&(o.cancelCommand=o.closeCommand=i(function(){p(e)}),o.modalVisibility.subscribe(function(t){t?(o.viewModelDom.show(),o.storeAndSetKeyScope(),M.popupVisibilityNames.push(o.viewModelName),o.viewModelDom.css("z-index",3e3+Object(M.popupVisibilityNames)().length+10),o.onShowTrigger&&o.onShowTrigger(!o.onShowTrigger()),Object(k.delegateRun)(o,"onShowWithDelay",[],500)):(Object(k.delegateRun)(o,"onHide"),Object(k.delegateRun)(o,"onHideWithDelay",[],500),o.onHideTrigger&&o.onHideTrigger(!o.onHideTrigger()),o.restoreKeyScope(),h("view-model-on-hide",e),M.popupVisibilityNames.remove(o.viewModelName),o.viewModelDom.css("z-index",2e3),E.a.delay(function(){return o.viewModelDom.hide()},300))})),h("view-model-pre-build",e,n),N.a.applyBindingAccessorsToNode(n[0],{translatorInit:!0,template:function(){return{name:o.viewModelTemplateID}}},o),Object(k.delegateRun)(o,"onBuild",[n]),o&&B.Popup===a&&o.registerPopupKeyDown(),h("view-model-post-build",e,n)):Object(k.log)("Cannot find view model position: "+a)}return e?e.__vm:null}function m(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],n=d(e);n&&(f(n),n.__vm&&n.__dom&&(Object(k.delegateRun)(n.__vm,"onBeforeShow",t||[]),n.__vm.modalVisibility(!0),Object(k.delegateRun)(n.__vm,"onShow",t||[]),h("view-model-on-show",n,t||[])))}function b(e){var t=d(e);t&&(f(t),t.__vm&&t.__dom&&Object(k.delegateRun)(t.__vm,"onWarmUp"))}function g(e){var t=d(e);return!(!t||!t.__vm)&&t.__vm.modalVisibility()}function y(e,t){var n=null,o=!1,i=null;""===Object(k.pString)(e)&&(e=U),""!==e&&((n=u(e))||(n=u(U))&&(t=e+"/"+t,e=U),n&&n.__started&&(o=x&&n===x,n.__builded||(n.__builded=!0,Object(k.isNonEmptyArray)(n.viewModels())&&E.a.each(n.viewModels(),function(e){f(e,n)}),Object(k.delegateRun)(n,"onBuild")),E.a.defer(function(){x&&!o&&(Object(k.delegateRun)(x,"onHide"),Object(k.delegateRun)(x,"onHideWithDelay",[],500),x.onHideTrigger&&x.onHideTrigger(!x.onHideTrigger()),Object(k.isNonEmptyArray)(x.viewModels())&&E.a.each(x.viewModels(),function(e){e.__vm&&e.__dom&&B.Popup!==e.__vm.viewModelPosition&&(e.__dom.hide(),e.__vm.viewModelVisibility(!1),Object(k.delegateRun)(e.__vm,"onHide"),Object(k.delegateRun)(e.__vm,"onHideWithDelay",[],500),e.__vm.onHideTrigger&&e.__vm.onHideTrigger(!e.__vm.onHideTrigger()))})),(x=n)&&!o&&(Object(k.delegateRun)(x,"onShow"),x.onShowTrigger&&x.onShowTrigger(!x.onShowTrigger()),Object(D.f)("screen-on-show",[x.screenName(),x]),Object(k.isNonEmptyArray)(x.viewModels())&&E.a.each(x.viewModels(),function(e){e.__vm&&e.__dom&&B.Popup!==e.__vm.viewModelPosition&&(Object(k.delegateRun)(e.__vm,"onBeforeShow"),e.__dom.show(),e.__vm.viewModelVisibility(!0),Object(k.delegateRun)(e.__vm,"onShow"),e.__vm.onShowTrigger&&e.__vm.onShowTrigger(!e.__vm.onShowTrigger()),Object(k.delegateRun)(e.__vm,"onShowWithDelay",[],200),h("view-model-on-show",e))})),(i=n&&n.__cross?n.__cross():null)&&i.parse(t)})))}function v(e){E.a.each(e,function(e){if(e){var t=new e,n=t?t.screenName():"";t&&""!==n&&(""===U&&(U=n),H[n]=t)}}),E.a.each(H,function(e){e&&!e.__started&&e.__start&&(e.__started=!0,e.__start(),Object(D.f)("screen-pre-start",[e.screenName(),e]),Object(k.delegateRun)(e,"onStart"),Object(D.f)("screen-post-start",[e.screenName(),e]))});var t=_.a.create();t.addRoute(/^([a-zA-Z0-9\-]*)\/?(.*)$/,y),I.a.initialized.add(t.parse,t),I.a.changed.add(t.parse,t),I.a.init(),E.a.delay(function(){return M.$html.removeClass("rl-started-trigger").addClass("rl-started")},100),E.a.delay(function(){return M.$html.addClass("rl-started-delay")},200)}function S(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];e="/"===(e="#"===e.substr(0,1)?e.substr(1):e).substr(0,1)?e.substr(1):e;var o=n?"replaceHash":"setHash";t?(I.a.changed.active=!1,I.a[o](e),I.a.changed.active=!0):(I.a.changed.active=!0,I.a[o](e),I.a.setHash(e))}function O(e){var t=e.name,n=e.type,o=e.templateID;return function(e){e&&(t&&(Object(k.isArray)(t)?e.__names=t:e.__names=[t],e.__name=e.__names[0]),n&&(e.__type=n),o&&(e.__templateID=o))}}function w(e){var t=e.name,n=e.templateID;return O({name:t,type:B.Popup,templateID:n})}function T(){var e=!(arguments.length>0&&void 0!==arguments[0])||arguments[0];return function(t,n,o){if(!n||!n.match(/Command$/))throw new Error('name "'+n+'" should end with Command suffix');var i=o.value||o.initializer(),a=Object(k.isFunc)(e)?e:function(){return!!e};return o.value=function(){if(a.call(this,this)){for(var e=arguments.length,t=Array(e),n=0;n1&&void 0!==arguments[1]&&arguments[1];f.a.defer(function(){b()("[data-i18n]",e).each(function(e,t){F(t)}),t&&S.bAnimationSupported&&b()(".i18n-animation[data-i18n]",e).letterfx({fx:"fall fade",backwards:!1,timing:50,fx_duration:"50ms",letter_end:"restore",element_end:"restore"})})}function a(){A.forEach(function(e){C[e[0]]=o(e[1])})}function r(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;e&&e(),t?E.subscribe(function(){e&&e(),t&&t()}):e&&E.subscribe(e)}function s(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;return e=p.a.parseInt(e,10)||0,y.Notification.ClientViewError===e&&t?t:(n=n&&p.a.parseInt(n,10)||0,Object(v.isUnd)(C[e])?n&&Object(v.isUnd)(C[n])?C[n]:"":C[e])}function c(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:y.Notification.UnknownNotification;return e&&e.ErrorCode?s(Object(v.pInt)(e.ErrorCode),e.ErrorMessage||""):s(t)}function l(e){var t="";switch(p.a.parseInt(e,10)||0){case y.UploadErrorCode.FileIsTooBig:t=o("UPLOAD/ERROR_FILE_IS_TOO_BIG");break;case y.UploadErrorCode.FilePartiallyUploaded:t=o("UPLOAD/ERROR_FILE_PARTIALLY_UPLOADED");break;case y.UploadErrorCode.FileNoUploaded:t=o("UPLOAD/ERROR_NO_FILE_UPLOADED");break;case y.UploadErrorCode.MissingTempFolder:t=o("UPLOAD/ERROR_MISSING_TEMP_FOLDER");break;case y.UploadErrorCode.FileOnSaveingError:t=o("UPLOAD/ERROR_ON_SAVING_FILE");break;case y.UploadErrorCode.FileType:t=o("UPLOAD/ERROR_FILE_TYPE");break;default:t=o("UPLOAD/ERROR_UNKNOWN")}return t}function u(e,t){var n=Object(v.microtime)();return S.$html.addClass("rl-changing-language"),new p.a.Promise(function(o,i){b.a.ajax({url:Object(w.n)(t,e),dataType:"script",cache:!0}).then(function(){f.a.delay(function(){j();var e=-1t.interval&&(t.isSystemFolder()||t.subScribed()&&t.checkable())&&o.push([t.interval,t.fullNameRaw]),t&&0t[0]?1:0}),s.a.find(o,function(n){var o=Object(p.e)(n[1]);return o&&(o.interval=t,e.push(n[1])),5<=e.length}),s.a.uniq(e)},e}();t.a=new f},function(e,t,n){"use strict";function o(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],o=0,i=0,a=[];if(Object(g.isNonEmptyArray)(e))for(i=e.length;o1&&void 0!==arguments[1]&&arguments[1];return o(this.from,e,t)},t.prototype.fromDkimData=function(){var e=["none",""];return Object(g.isNonEmptyArray)(this.from)&&1===this.from.length&&this.from[0]&&this.from[0].dkimStatus&&(e=[this.from[0].dkimStatus,this.from[0].dkimValue||""]),e},t.prototype.toToLine=function(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];return o(this.to,e,t)},t.prototype.ccToLine=function(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];return o(this.cc,e,t)},t.prototype.bccToLine=function(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];return o(this.bcc,e,t)},t.prototype.replyToToLine=function(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];return o(this.replyTo,e,t)},t.prototype.lineAsCss=function(){return L()({deleted:this.deleted(),"deleted-mark":this.deletedMark(),selected:this.selected(),checked:this.checked(),flagged:this.flagged(),unseen:this.unseen(),answered:this.answered(),forwarded:this.forwarded(),focused:this.focused(),important:this.isImportant(),withAttachments:this.hasAttachments(),new:this.newForAnimation(),emptySubject:""===this.subject(),hasUnseenSubMessage:this.hasUnseenSubMessage(),hasFlaggedSubMessage:this.hasFlaggedSubMessage()})},t.prototype.hasVisibleAttachments=function(){return!!p.a.find(this.attachments(),function(e){return!e.isLinked})},t.prototype.findAttachmentByCid=function(e){var t=null,n=this.attachments();return Object(g.isNonEmptyArray)(n)&&(e=e.replace(/^<+/,"").replace(/>+$/,""),t=p.a.find(n,function(t){return e===t.cidWithOutTags})),t||null},t.prototype.findAttachmentByContentLocation=function(e){var t=null,n=this.attachments();return Object(g.isNonEmptyArray)(n)&&(t=p.a.find(n,function(t){return e===t.contentLocation})),t||null},t.prototype.messageId=function(){return this.sMessageId},t.prototype.inReplyTo=function(){return this.sInReplyTo},t.prototype.references=function(){return this.sReferences},t.prototype.fromAsSingleEmail=function(){return Object(g.isArray)(this.from)&&this.from[0]?this.from[0].email:""},t.prototype.viewLink=function(){return Object(O.q)(this.requestHash)},t.prototype.downloadLink=function(){return Object(O.p)(this.requestHash)},t.prototype.replyEmails=function(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=[],o=Object(g.isUnd)(e)?{}:e;return r(this.replyTo,o,n),0===n.length&&r(this.from,o,n),0!==n.length||t?n:this.replyEmails({},!0)},t.prototype.replyAllEmails=function(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=[],o=[],i=Object(g.isUnd)(e)?{}:e;return r(this.replyTo,i,n),0===n.length&&r(this.from,i,n),r(this.to,i,n),r(this.cc,i,o),0!==n.length||t?[n,o]:[this.replyAllEmails({},!0)[0],o]},t.prototype.textBodyToString=function(){return this.body?this.body.html():""},t.prototype.attachmentsToStringLine=function(){var e=p.a.map(this.attachments(),function(e){return e.fileName+" ("+e.friendlySize+")"});return e&&00&&void 0!==arguments[0]&&arguments[0];this.showLazyExternalImagesInBody();var t=this.dateTimeStampInUTC()||0,n=this.ccToLine(!1),o=00&&void 0!==arguments[0]&&arguments[0];if(this.body&&this.body.data("rl-has-images")){this.hasImages(!1),this.body.data("rl-has-images",!1);var t=this.proxy?"data-x-additional-src":"data-x-src";m()("["+t+"]",this.body).each(function(){var n=m()(this);e&&n.is("img")?n.addClass("lazy").attr("data-original",n.attr(t)).removeAttr("data-loaded"):n.attr("src",n.attr(t)).removeAttr("data-loaded")}),t=this.proxy?"data-x-additional-style-url":"data-x-style-url",m()("["+t+"]",this.body).each(function(){var e=m()(this),n=Object(g.trim)(e.attr("style"));n=""===n?"":";"===n.substr(-1)?n+" ":n+"; ",e.attr("style",n+e.attr(t))}),e&&(this.lozad(),S.$win.resize()),Object(g.windowResize)(500)}},t.prototype.showInternalImages=function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];if(this.body&&!this.body.data("rl-init-internal-images")){this.body.data("rl-init-internal-images",!0);var n=this;m()("[data-x-src-cid]",this.body).each(function(){var e=m()(this),o=n.findAttachmentByCid(e.attr("data-x-src-cid"));o&&o.download&&(t&&e.is("img")?e.addClass("lazy").attr("data-original",o.linkPreview()):e.attr("src",o.linkPreview()))}),m()("[data-x-src-location]",this.body).each(function(){var e=m()(this),o=n.findAttachmentByContentLocation(e.attr("data-x-src-location"));o||(o=n.findAttachmentByCid(e.attr("data-x-src-location"))),o&&o.download&&(t&&e.is("img")?e.addClass("lazy").attr("data-original",o.linkPreview()):e.attr("src",o.linkPreview()))}),m()("[data-x-style-cid]",this.body).each(function(){var e="",t="",o=m()(this),i=n.findAttachmentByCid(o.attr("data-x-style-cid"));i&&i.linkPreview&&""!==(t=o.attr("data-x-style-cid-name"))&&(e=""===(e=Object(g.trim)(o.attr("style")))?"":";"===e.substr(-1)?e+" ":e+"; ",o.attr("style",e+t+": url('"+i.linkPreview()+"')"))}),t&&p.a.delay(function(){return e.lozad()},300),Object(g.windowResize)(500)}},t.prototype.storeDataInDom=function(){this.body&&(this.body.data("rl-is-html",!!this.isHtml()),this.body.data("rl-has-images",!!this.hasImages()))},t.prototype.fetchDataFromDom=function(){this.body&&(this.isHtml(!!this.body.data("rl-is-html")),this.hasImages(!!this.body.data("rl-has-images")))},t.prototype.replacePlaneTextBody=function(e){this.body&&this.body.html(e).addClass("b-text-part plain")},t.prototype.flagHash=function(){return[this.deleted(),this.deletedMark(),this.unseen(),this.flagged(),this.answered(),this.forwarded(),this.isReadReceipt()].join(",")},t}(n(36).a),U=n(9),H=n(26),B=n(31),G=n(28),K=n(62),V=n(20),z=n(17),q=function(){function e(){c()(this,e),this.staticMessage=new x,this.messageList=h.a.observableArray([]).extend({rateLimit:0}),this.messageListCount=h.a.observable(0),this.messageListSearch=h.a.observable(""),this.messageListThreadUid=h.a.observable(""),this.messageListPage=h.a.observable(1),this.messageListPageBeforeThread=h.a.observable(1),this.messageListError=h.a.observable(""),this.messageListEndFolder=h.a.observable(""),this.messageListEndSearch=h.a.observable(""),this.messageListEndThreadUid=h.a.observable(""),this.messageListEndPage=h.a.observable(1),this.messageListLoading=h.a.observable(!1),this.messageListIsNotCompleted=h.a.observable(!1),this.messageListCompleteLoadingThrottle=h.a.observable(!1).extend({throttle:200}),this.messageListCompleteLoadingThrottleForAnimation=h.a.observable(!1).extend({specialThrottle:700}),this.messageListDisableAutoSelect=h.a.observable(!1).extend({falseTimeout:500}),this.selectorMessageSelected=h.a.observable(null),this.selectorMessageFocused=h.a.observable(null),this.message=h.a.observable(null),this.message.viewTrigger=h.a.observable(!1),this.messageError=h.a.observable(""),this.messageCurrentLoading=h.a.observable(!1),this.messageLoadingThrottle=h.a.observable(!1).extend({throttle:b.Magics.Time50ms}),this.messageFullScreenMode=h.a.observable(!1),this.messagesBodiesDom=h.a.observable(null),this.messageActiveDom=h.a.observable(null),this.computers(),this.subscribers(),this.onMessageResponse=p.a.bind(this.onMessageResponse,this),this.purgeMessageBodyCacheThrottle=p.a.throttle(this.purgeMessageBodyCache,b.Magics.Time30s)}return e.prototype.computers=function(){var e=this;this.messageLoading=h.a.computed(function(){return e.messageCurrentLoading()}),this.messageListEndHash=h.a.computed(function(){return e.messageListEndFolder()+"|"+e.messageListEndSearch()+"|"+e.messageListEndThreadUid()+"|"+e.messageListEndPage()}),this.messageListPageCount=h.a.computed(function(){var t=u.a.Math.ceil(e.messageListCount()/G.a.messagesPerPage());return 0>=t?1:t}),this.mainMessageListSearch=h.a.computed({read:this.messageListSearch,write:function(t){Object(U.setHash)(Object(O.o)(D.a.currentFolderFullNameHash(),1,Object(g.trim)(t.toString()),e.messageListThreadUid()))}}),this.messageListCompleteLoading=h.a.computed(function(){var t=e.messageListLoading(),n=e.messageListIsNotCompleted();return t||n}),this.isMessageSelected=h.a.computed(function(){return null!==e.message()}),this.messageListChecked=h.a.computed(function(){return p.a.filter(e.messageList(),function(e){return e.checked()})}).extend({rateLimit:0}),this.hasCheckedMessages=h.a.computed(function(){return 0n.data("rl-cache-count")&&(n.addClass("rl-cache-purge"),e+=1)}),02&&void 0!==arguments[2]?arguments[2]:"",i=arguments.length>3&&void 0!==arguments[3]&&arguments[3];t=p.a.map(t,function(e){return Object(g.pInt)(e)});var a=0,r=this.messageList(),s=this.message(),c=D.a.trashFolder(),l=D.a.spamFolder(),u=Object(y.e)(e),d=""===o?null:Object(y.e)(o||""),h=D.a.currentFolderFullNameRaw()===e?p.a.filter(r,function(e){return e&&-1').insertBefore(e).on("click.rlBlockquoteSwitcher",function(){e.toggleClass("hidden-bq"),Object(g.windowResize)()}).after("
").before("
"))})}},e.prototype.initOpenPgpControls=function(e,t){e&&e.find&&e.find(".b-plain-openpgp:not(.inited)").each(function(){M.a.initMessageBodyControls(m()(this),t)})},e.prototype.setMessage=function(e,t){var n=!1,o=null,i="",a="",r="",s=!1,c=this.messagesBodiesDom(),l=this.selectorMessageSelected(),u=this.message();if(e&&u&&e.Result&&"Object/Message"===e.Result["@Object"]&&u.folderFullNameRaw===e.Result.Folder){var d=u.threads();if(u.uid!==e.Result.Uid&&1').text(a)).html():v&&u.isPgpEncrypted()?S.$div.append(m()('
').text(a)).html():"
"+r+"
",S.$div.empty(),u.isPgpSigned(s),u.isPgpEncrypted(v)}else r="
"+r+"
";else f=!1,r="
"+r+"
";S.data.iMessageBodyCacheCount+=1,(o=m()('
').hide().addClass("rl-cache-class")).data("rl-cache-count",S.data.iMessageBodyCacheCount),o.html(Object(g.findEmailAndLinks)(r)).addClass("b-text-part "+(f?"html":"plain")),u.isHtml(!!f),u.hasImages(!!e.Result.HasExternals),u.body=o,u.body&&c.append(u.body),u.storeDataInDom(),e.Result.HasInternals&&u.showInternalImages(!0),u.hasImages()&&G.a.showImages()&&u.showExternalImages(!0),this.purgeMessageBodyCacheThrottle()}this.messageActiveDom(u.body),this.hideMessageBodies(),o&&(this.initOpenPgpControls(o,u),this.initBlockquoteSwitcher(o)),u.body.show()}Object(y.n)(u),(u.unseen()||u.hasUnseenSubMessage())&&Object(V.a)().messageListAction(u.folderFullNameRaw,b.MessageSetAction.SetSeen,[u]),n&&(u=this.message(),l&&u&&(u.folderFullNameRaw!==l.folderFullNameRaw||u.uid!==l.uid)?(this.selectorMessageSelected(null),1===this.messageList().length&&this.selectorMessageFocused(null)):!l&&u&&(l=p.a.find(this.messageList(),function(e){return e&&e.folderFullNameRaw===u.folderFullNameRaw&&e.uid===u.uid}))&&(this.selectorMessageSelected(l),this.selectorMessageFocused(l))),Object(g.windowResize)()}}},e.prototype.selectMessage=function(e){e?(this.message(this.staticMessage.populateByMessageListItem(e)),this.populateMessageBody(this.message())):this.message(null)},e.prototype.selectMessageByFolderAndUid=function(e,t){e&&t?(this.message(this.staticMessage.populateByMessageListItem(null)),this.message().folderFullNameRaw=e,this.message().uid=t,this.populateMessageBody(this.message())):this.message(null)},e.prototype.populateMessageBody=function(e){e&&z.a.message(this.onMessageResponse,e.folderFullNameRaw,e.uid)&&this.messageCurrentLoading(!0)},e.prototype.onMessageResponse=function(e,t,n){this.hideMessageBodies(),this.messageCurrentLoading(!1),b.StorageResultType.Success===e&&t&&t.Result?this.setMessage(t,n):b.StorageResultType.Unload===e?(this.message(null),this.messageError("")):b.StorageResultType.Abort!==e&&(this.message(null),this.messageError(t&&t.ErrorCode?Object(w.getNotification)(t.ErrorCode):Object(w.getNotification)(b.Notification.UnknownError)))},e.prototype.calculateMessageListHash=function(e){return p.a.map(e,function(e){return e.hash+"_"+e.threadsLen()+"_"+e.flagHash()}).join("|")},e.prototype.setMessageList=function(e,t){if(e&&e.Result&&"Collection/MessageCollection"===e.Result["@Object"]&&e.Result["@Collection"]&&Object(g.isArray)(e.Result["@Collection"])){var n=0,o=!1,i=[],a=Object(T.momentNowUnix)(),r=Object(g.pInt)(e.Result.MessageResultCount),s=Object(g.pInt)(e.Result.Offset),c=Object(y.e)(Object(g.isNormal)(e.Result.Folder)?e.Result.Folder:"");c&&!t&&(c.interval=a,Object(y.q)(e.Result.Folder,e.Result.FolderHash),Object(g.isNormal)(e.Result.MessageCount)&&c.messageCountAll(e.Result.MessageCount),Object(g.isNormal)(e.Result.MessageUnseenCount)&&(Object(g.pInt)(c.messageCountUnread())!==Object(g.pInt)(e.Result.MessageUnseenCount)&&(o=!0),c.messageCountUnread(e.Result.MessageUnseenCount)),this.initUidNextAndNewMessages(c.fullNameRaw,e.Result.UidNext,e.Result.NewMessages)),o&&c&&Object(y.c)(c.fullNameRaw),p.a.each(e.Result["@Collection"],function(e){if(e&&"Object/Message"===e["@Object"]){var o=x.newInstanceFromJson(e);o&&(Object(y.l)(o.folderFullNameRaw,o.uid)&&5>=n&&(n+=1,o.newForAnimation(!0)),o.deleted(!1),t?Object(y.n)(o):Object(y.u)(o),i.push(o))}}),this.messageListCount(r),this.messageListSearch(Object(g.isNormal)(e.Result.Search)?e.Result.Search:""),this.messageListPage(u.a.Math.ceil(s/G.a.messagesPerPage()+1)),this.messageListThreadUid(Object(g.isNormal)(e.Result.ThreadUid)?Object(g.pString)(e.Result.ThreadUid):""),this.messageListEndFolder(Object(g.isNormal)(e.Result.Folder)?e.Result.Folder:""),this.messageListEndSearch(this.messageListSearch()),this.messageListEndThreadUid(this.messageListThreadUid()),this.messageListEndPage(this.messageListPage()),this.messageListDisableAutoSelect(!0),this.messageList(i),this.messageListIsNotCompleted(!1),Object(y.d)(),c&&(t||o||G.a.useThreads())&&Object(V.a)().folderInformation(c.fullNameRaw,i)}else this.messageListCount(0),this.messageList([]),this.messageListError(Object(w.getNotification)(e&&e.ErrorCode?e.ErrorCode:b.Notification.CantGetMessageList))},e}();t.a=new q},function(e,t,n){"use strict";function o(e,t){e=Object(R.trim)(e),t(H&&""!==e?I.h(e):"",e)}function i(e,t){return e+"#"+t}function a(e,t){U[i(e,t)]=!0}function r(e,t){return!0===U[i(e,t)]}function s(e,t){k[i(e,t)]=!0}function c(e,t){return!!k[i(e,t)]&&(k[i(e,t)]=null,!0)}function l(){k={}}function u(){return""===x?"INBOX":x}function d(e){return""!==e&&_[e]?_[e]:""}function p(e,t){_[e]=t,"INBOX"!==t&&""!==x||(x=t)}function h(e){return""!==e&&P[e]?P[e]:""}function f(e,t){""!==e&&(P[e]=t)}function m(e){return""!==e&&D[e]?D[e]:""}function b(e,t){D[e]=t}function g(e){return""!==e&&L[e]?L[e]:null}function y(e,t){L[e]=t}function v(e){y(e,null)}function S(e,t){return M[e]&&M[e][t]?M[e][t]:null}function O(e,t,n){M[e]||(M[e]={}),M[e][t]=n}function w(e){M[e]={}}function T(e){if(e){var t=e.uid,n=S(e.folderFullNameRaw,t);if(n&&00&&void 0!==arguments[0]?arguments[0]:"";return W+Object(V.pString)(e)}function r(){return ee?q:Y+te}function s(){return q}function c(e,t,n){return n=Object(V.isUnd)(n)?ne:n,Y+"/Raw/"+$+"/"+n+"/"+e+"/"+$+"/"+t}function l(e,t){return c("Download",e,t)}function u(e,t){return c("View",e,t)}function d(e,t){return c("ViewThumbnail",e,t)}function p(e,t){return c("ViewAsPlain",e,t)}function h(e,t){return c("FramedView",e,t)}function f(e){return Y+"/"+e+"/"+$+"/"+ne+"/"}function m(){return f("Upload")}function b(){return f("UploadContacts")}function g(){return f("UploadBackground")}function y(){return f("Append")}function v(e){return f("Change")+Object(V.encodeURIComponent)(e)+"/"}function S(e){return f("Ajax")+e}function O(e){return Y+"/Raw/"+$+"/"+ne+"/ViewAsPlain/"+$+"/"+e}function w(e){return Y+"/Raw/"+$+"/"+ne+"/Download/"+$+"/"+e}function T(e){return Y+"/Raw/0/Avatar/"+Object(V.encodeURIComponent)(e)+"/"}function C(e){return Y+"/Raw/"+$+"/"+ne+"/UserBackground/"+$+"/"+e}function A(){return Y+"/Info"}function E(e,t){return Y+"/Lang/0/"+(t?"Admin":"App")+"/"+K.a.encodeURI(e)+"/"+J+"/"}function F(){return Y+"/Raw/"+$+"/"+ne+"/ContactsVcf/"}function j(){return Y+"/Raw/"+$+"/"+ne+"/ContactsCsv/"}function N(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];return Y+"SocialGoogle"+(""!==ne?"/"+$+"/"+ne+"/":"")+(e?"&xauth=1":"")}function R(){return Y+"SocialTwitter"+(""!==ne?"/"+$+"/"+ne+"/":"")}function I(){return Y+"SocialFacebook"+(""!==ne?"/"+$+"/"+ne+"/":"")}function L(e){return Q+e}function _(){return L("css/images/empty-contact.png")}function P(e){return L("sounds/"+e)}function D(){return L("css/images/icom-message-notification.png")}function M(){return L("js/min/openpgp.min.js")}function k(){return L("js/min/openpgp.worker.min.js")}function x(e){var t=Z;return"@custom"===e.substr(-7)&&(e=Object(V.trim)(e.substring(0,e.length-7)),t=X),t+"themes/"+K.a.encodeURI(e)+"/images/preview.png"}function U(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"INBOX";return W+"mailbox/"+e}function H(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";return W+"settings"+(e?"/"+e:"")}function B(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"",o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"";t=Object(V.isNormal)(t)?Object(V.pInt)(t):1,n=Object(V.pString)(n);var i=W+"mailbox/";if(""!==e){var a=Object(V.pInt)(o);i+=K.a.encodeURI(e)+(0>2,r=(3&n)<<4|(o=e.charCodeAt(l++))>>4,s=(15&o)<<2|(i=e.charCodeAt(l++))>>6,c=63&i,isNaN(o)?s=c=64:isNaN(i)&&(c=64),t=t+m.charAt(a)+m.charAt(r)+m.charAt(s)+m.charAt(c);return t},decode:function(e){var t="",n=void 0,o=void 0,i=void 0,a=void 0,r=void 0,s=void 0,c=0;for(e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");c>4,o=(15&a)<<4|(r=m.indexOf(e.charAt(c++)))>>2,i=(3&r)<<6|(s=m.indexOf(e.charAt(c++))),t+=String.fromCharCode(n),64!==r&&(t+=String.fromCharCode(o)),64!==s&&(t+=String.fromCharCode(i));return b._utf8_decode(t)},_utf8_encode:function(e){for(var t="",n=0,o=(e=e.replace(/\r\n/g,"\n")).length,i=0;n127&&i<2048?(t+=String.fromCharCode(i>>6|192),t+=String.fromCharCode(63&i|128)):(t+=String.fromCharCode(i>>12|224),t+=String.fromCharCode(i>>6&63|128),t+=String.fromCharCode(63&i|128));return t},_utf8_decode:function(e){for(var t="",n=0,o=0,i=0,a=0;n191&&o<224?(i=e.charCodeAt(n+1),t+=String.fromCharCode((31&o)<<6|63&i),n+=2):(i=e.charCodeAt(n+1),a=e.charCodeAt(n+2),t+=String.fromCharCode((15&o)<<12|(63&i)<<6|63&a),n+=3);return t}},g=(b.decode,b.encode,b.urlsafe_encode),y=n(5),v=n(26),S=n(28),O=n(20),w=function(e){function t(){i()(this,t);var n=r()(this,e.call(this));return n.oRequests={},n}return c()(t,e),t.prototype.folders=function(e){this.defaultRequest(e,"Folders",{SentFolder:y.settingsGet("SentFolder"),DraftFolder:y.settingsGet("DraftFolder"),SpamFolder:y.settingsGet("SpamFolder"),TrashFolder:y.settingsGet("TrashFolder"),ArchiveFolder:y.settingsGet("ArchiveFolder")},null,"",["Folders"])},t.prototype.login=function(e,t,n,o,i,a,r,s){this.defaultRequest(e,"Login",{Email:t,Login:n,Password:o,Language:a||"",AdditionalCode:r||"",AdditionalCodeSignMe:s?"1":"0",SignMe:i?"1":"0"})},t.prototype.getTwoFactor=function(e){this.defaultRequest(e,"GetTwoFactorInfo")},t.prototype.createTwoFactor=function(e){this.defaultRequest(e,"CreateTwoFactorSecret")},t.prototype.clearTwoFactor=function(e){this.defaultRequest(e,"ClearTwoFactorInfo")},t.prototype.showTwoFactorSecret=function(e){this.defaultRequest(e,"ShowTwoFactorSecret")},t.prototype.testTwoFactor=function(e,t){this.defaultRequest(e,"TestTwoFactorInfo",{Code:t})},t.prototype.enableTwoFactor=function(e,t){this.defaultRequest(e,"EnableTwoFactor",{Enable:t?"1":"0"})},t.prototype.clearTwoFactorInfo=function(e){this.defaultRequest(e,"ClearTwoFactorInfo")},t.prototype.contactsSync=function(e){this.defaultRequest(e,"ContactsSync",null,p.d)},t.prototype.saveContactsSyncData=function(e,t,n,o,i){this.defaultRequest(e,"SaveContactsSyncData",{Enable:t?"1":"0",Url:n,User:o,Password:i})},t.prototype.accountSetup=function(e,t,n){var o=!(arguments.length>3&&void 0!==arguments[3])||arguments[3];this.defaultRequest(e,"AccountSetup",{Email:t,Password:n,New:o?"1":"0"})},t.prototype.accountDelete=function(e,t){this.defaultRequest(e,"AccountDelete",{EmailToDelete:t})},t.prototype.accountsAndIdentitiesSortOrder=function(e,t,n){this.defaultRequest(e,"AccountsAndIdentitiesSortOrder",{Accounts:t,Identities:n})},t.prototype.identityUpdate=function(e,t,n,o,i,a,r,s){this.defaultRequest(e,"IdentityUpdate",{Id:t,Email:n,Name:o,ReplyTo:i,Bcc:a,Signature:r,SignatureInsertBefore:s?"1":"0"})},t.prototype.identityDelete=function(e,t){this.defaultRequest(e,"IdentityDelete",{IdToDelete:t})},t.prototype.accountsAndIdentities=function(e){this.defaultRequest(e,"AccountsAndIdentities")},t.prototype.accountsCounts=function(e){this.defaultRequest(e,"AccountsCounts")},t.prototype.filtersSave=function(e,t,n,o){this.defaultRequest(e,"FiltersSave",{Raw:n,RawIsActive:Object(d.boolToAjax)(o),Filters:u.a.map(t,function(e){return e.toJson()})})},t.prototype.filtersGet=function(e){this.defaultRequest(e,"Filters",{})},t.prototype.templates=function(e){this.defaultRequest(e,"Templates",{})},t.prototype.templateGetById=function(e,t){this.defaultRequest(e,"TemplateGetByID",{ID:t})},t.prototype.templateDelete=function(e,t){this.defaultRequest(e,"TemplateDelete",{IdToDelete:t})},t.prototype.templateSetup=function(e,t,n,o){this.defaultRequest(e,"TemplateSetup",{ID:t,Name:n,Body:o})},t.prototype.messageList=function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:20,i=arguments.length>4&&void 0!==arguments[4]?arguments[4]:"",a=arguments.length>5&&void 0!==arguments[5]?arguments[5]:"",r=arguments.length>6&&void 0!==arguments[6]&&arguments[6];t=Object(d.pString)(t);var s=Object(h.g)(t),c=v.a.threadsAllowed()&&S.a.useThreads(),l=Object(h.h)()===t?Object(h.i)(t):"";return""===s||""!==i&&-1!==i.indexOf("is:")?this.defaultRequest(e,"MessageList",{Folder:t,Offset:n,Limit:o,Search:i,UidNext:l,UseThreads:c?"1":"0",ThreadUid:c?a:""},""===i?p.g:p.m,"",r?[]:["MessageList"]):this.defaultRequest(e,"MessageList",{},""===i?p.g:p.m,"MessageList/"+Object(f.E)()+"/"+g([t,n,o,i,v.a.projectHash(),s,l,c?"1":"0",c?a:""].join(String.fromCharCode(0))),r?[]:["MessageList"])},t.prototype.messageUploadAttachments=function(e,t){this.defaultRequest(e,"MessageUploadAttachments",{Attachments:t},999e3)},t.prototype.message=function(e,t,n){return t=Object(d.pString)(t),n=Object(d.pInt)(n),!!(Object(h.e)(t)&&02&&void 0!==arguments[2]?arguments[2]:[],o=!0,i=[];Object(d.isArray)(n)&&03&&void 0!==arguments[3]?arguments[3]:null;this.defaultRequest(e,"MessageSetSeenToAll",{Folder:t,SetAction:n?"1":"0",ThreadUids:o?o.join(","):""})},t.prototype.saveMessage=function(e,t,n,o,i,a,r,s,c,l,u,d,h,f,m,b,g){this.defaultRequest(e,"SaveMessage",{IdentityID:t,MessageFolder:n,MessageUid:o,DraftFolder:i,To:a,Cc:r,Bcc:s,ReplyTo:c,Subject:l,TextIsHtml:u?"1":"0",Text:d,DraftInfo:f,InReplyTo:m,References:b,MarkAsImportant:g?"1":"0",Attachments:h},p.l)},t.prototype.sendReadReceiptMessage=function(e,t,n,o,i,a){this.defaultRequest(e,"SendReadReceiptMessage",{MessageFolder:t,MessageUid:n,ReadReceipt:o,Subject:i,Text:a})},t.prototype.sendMessage=function(e,t,n,o,i,a,r,s,c,l,u,d,h,f,m,b,g,y,v){this.defaultRequest(e,"SendMessage",{IdentityID:t,MessageFolder:n,MessageUid:o,SentFolder:i,To:a,Cc:r,Bcc:s,ReplyTo:c,Subject:l,TextIsHtml:u?"1":"0",Text:d,DraftInfo:f,InReplyTo:m,References:b,Dsn:g?"1":"0",ReadReceiptRequest:y?"1":"0",MarkAsImportant:v?"1":"0",Attachments:h},p.n)},t.prototype.saveSystemFolders=function(e,t){this.defaultRequest(e,"SystemFoldersUpdate",t)},t.prototype.saveSettings=function(e,t){this.defaultRequest(e,"SettingsUpdate",t)},t.prototype.saveSettingsHelper=function(e,t,n){var o=this;return function(i){var a;o.saveSettings(n||null,((a={})[e]=t?t(i):i,a))}},t.prototype.changePassword=function(e,t,n){this.defaultRequest(e,"ChangePassword",{PrevPassword:t,NewPassword:n})},t.prototype.folderClear=function(e,t){this.defaultRequest(e,"FolderClear",{Folder:t})},t.prototype.folderSetSubscribe=function(e,t,n){this.defaultRequest(e,"FolderSubscribe",{Folder:t,Subscribe:n?"1":"0"})},t.prototype.folderSetCheckable=function(e,t,n){this.defaultRequest(e,"FolderCheckable",{Folder:t,Checkable:n?"1":"0"})},t.prototype.messagesMove=function(e,t,n,o,i,a){this.defaultRequest(e,"MessageMove",{FromFolder:t,ToFolder:n,Uids:o.join(","),MarkAsRead:a?"1":"0",Learning:i||""},null,"",["MessageList"])},t.prototype.messagesCopy=function(e,t,n,o){this.defaultRequest(e,"MessageCopy",{FromFolder:t,ToFolder:n,Uids:o.join(",")})},t.prototype.messagesDelete=function(e,t,n){this.defaultRequest(e,"MessageDelete",{Folder:t,Uids:n.join(",")},null,"",["MessageList"])},t.prototype.appDelayStart=function(e){this.defaultRequest(e,"AppDelayStart")},t.prototype.quota=function(e){this.defaultRequest(e,"Quota")},t.prototype.contacts=function(e,t,n,o){this.defaultRequest(e,"Contacts",{Offset:t,Limit:n,Search:o},null,"",["Contacts"])},t.prototype.contactSave=function(e,t,n,o){this.defaultRequest(e,"ContactSave",{RequestUid:t,Uid:Object(d.trim)(n),Properties:o})},t.prototype.contactsDelete=function(e,t){this.defaultRequest(e,"ContactsDelete",{Uids:t.join(",")})},t.prototype.suggestions=function(e,t,n){this.defaultRequest(e,"Suggestions",{Query:t,Page:n},null,"",["Suggestions"])},t.prototype.clearUserBackground=function(e){this.defaultRequest(e,"ClearUserBackground")},t.prototype.facebookUser=function(e){this.defaultRequest(e,"SocialFacebookUserInformation")},t.prototype.facebookDisconnect=function(e){this.defaultRequest(e,"SocialFacebookDisconnect")},t.prototype.twitterUser=function(e){this.defaultRequest(e,"SocialTwitterUserInformation")},t.prototype.twitterDisconnect=function(e){this.defaultRequest(e,"SocialTwitterDisconnect")},t.prototype.googleUser=function(e){this.defaultRequest(e,"SocialGoogleUserInformation")},t.prototype.googleDisconnect=function(e){this.defaultRequest(e,"SocialGoogleDisconnect")},t.prototype.socialUsers=function(e){this.defaultRequest(e,"SocialUsers")},t}(n(115).a);t.a=new w},function(e,t,n){e.exports={default:n(111),__esModule:!0}},function(e,t){e.exports=window.key},function(e,t,n){"use strict";function o(){return n(173).default}n.d(t,"a",function(){return o})},,function(e,t,n){"use strict";function o(e,t,n){Object(s.isObject)(e)?(n=t||null,t=null,r.a.each(e,function(e,t){o(t,e,n)})):(Object(s.isUnd)(l[e])&&(l[e]=[]),l[e].push([t,n]))}function i(e,t){c.f("rl-pub",[e,t]),Object(s.isUnd)(l[e])||r.a.each(l[e],function(e){e[0]&&e[0].apply(e[1]||null,t||[])})}n.d(t,"b",function(){return o}),n.d(t,"a",function(){return i});var a=n(4),r=n.n(a),s=n(2),c=n(29),l={}},function(e,t,n){"use strict";n.d(t,"i",function(){return o}),n.d(t,"j",function(){return i}),n.d(t,"c",function(){return a}),n.d(t,"g",function(){return r}),n.d(t,"m",function(){return s}),n.d(t,"n",function(){return c}),n.d(t,"l",function(){return l}),n.d(t,"d",function(){return u}),n.d(t,"r",function(){return d}),n.d(t,"b",function(){return p}),n.d(t,"h",function(){return h}),n.d(t,"p",function(){return f}),n.d(t,"o",function(){return m}),n.d(t,"k",function(){return b}),n.d(t,"a",function(){return g}),n.d(t,"q",function(){return y}),n.d(t,"f",function(){return v}),n.d(t,"e",function(){return S});var o=20,i=[10,20,30,50,100],a=50,r=3e4,s=3e5,c=3e5,l=2e5,u=2e5,d="__UNUSE__",p="rlcsc",h=143,f=25,m=4190,b=15,g=7,y=10,v="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC4AAAAuCAYAAABXuSs3AAAHHklEQVRoQ7VZW08bVxCeXRuwIbTGXIwNtBBaqjwgVUiR8lDlbza9qe1DpVZ9aNQ/0KpPeaJK07SpcuEeCEmUAObm21bfrL9lONjexSYrWfbunj37zXdmvpkz9oIgCKTD0Wg0xPd94TDP83Q0zvWa50vzklSrdanVanqf4/D84GBGr+F+Op3S8fqoJxLOdnZgTvsO/nYhenHA+UC7CWF1uXwkb9++ldPTUwVerVbVqFQqpR8YPjQ0JCMjI5LNDijoRgP3PQVu5+5Eor2XGLg7IV4GkIdHJ/LmzRs5ODiIwNbrdR0O0GCcq4Xz4eFhmZyclP7+tDQaIik/BG5XKQn4SwG3zJTLZXn9+rUclI8UHD5YVoDDN8bSzXhONwL48fFxGR4eilzFZT1uFRIB5yT8BqCdnR3Z3d0VP9Un6XRawYJpggVrZBv38ME4XKtUKnLt2jUplUoy1PR/l3U7T6sVSAQcgMAkj8PDQ9ne3pajoyMRL7zeKsYZWHgWYDGmv78/mmdwcFA+mJlSgziHDWrERrsjEXDXegTi1tZW+DLxI2bxIrqFNYTXyDyCFweMAHCwb8e4RnTNuOsqe3t7sra21pTD0Kct666E8XlcZyzw9/RUUXK5nK5oUinUQI6TQ3cynO/v78vq6qrKXCNwlTiJJpyNGc3nZHp6uqV2dwrQWOCtZBDAV1ZWwsQk7f0wiQn5kffbAu/0/KWBYzIC1+XukfGx0RGZmppKlC2tIV0Bh4aDcZW7HhkfH8urLLZL7T2pihvlkMNnz56FiadHxicL41IsFpN41bkxsYxbRdFo9jwB8KdPn14J8KnSpBQKhQs63nPmbCVRcBUAR2Lq1VVmpksyMTFxAXjcEsQybiegESionjx5osCZOeNe1O4+EhCAX7bQSgQcxRHTMgAgcz5+/Dis/hL4uHU3/B4YGNASGHIKxuEql0k+l05AeIAF1vPnz5VxFFmdDlaJrMtZITJeSsXCOTlMunKxjLtMYOKNjQ158eJFuAuKkUOb5sEwgff19SkJUBVkThZUbnXZrtCKBQ6gbnWIkjZpyne3ejAWoGnA7Icz6irvBLgbOMicCM6TkxPx/LAkbXfgWcsazuE2kFRsKD5Z+CiqDumKncpZvieWcS6dDVD8xiYCNflpJdwcdwJOf9airLmVQ7DPzMxIYWLsXGXoVqLt5k0M3K3JUVPDZdbWNzsCp48TPFdvdnZWUz32nDha7bJ63kgAJPzSdRks9/Kf9xMJAQ1gq2NpaUmy2Yz4zar4nQC3xb99AQwCcGzLAAwuhG8YiWvcOKts+r4GOe5nMhm5efOm9lUA3E3vSZJRrKvE0fnPv//Jy5cvo5cTHIPQbSjhOoqq69evS19f6lxDKK4+sVhigZPtKJqbrQeqxd5+WR4+fKgqgT0k2XX3nhiPgETWXFhYkFzuPZ2yVq1GTSOXpE47/VjgNnD4m4GG7/LhsTx69EiwD4Vr2MwIIxgbAH18fKx1yfz8vEogNvGtWnCuhLZa9UTAreVWFsHy/b/+Vrbdl7E5REMQD2jDoUbByty+/ZnU64GkU2HzyJLhktU1cLv8nARgkYS2d3ajAgwG8qU2oLmDZ92CMaOjo7K4uCiZgbDWaRWgnZhPxLhrMUCvr69riwKZk1LHF7XqrWAO9hJxH6ozNzcnCx/PqztZg9mf6SQMscCtm2C5ke4BGMlHWTUp36036AJajDVrFMzBrhhWslQsSrFYiOqVpMriNYIgqFRq2j3FAb/zffT6zuxFXxsNzs3NTXn16lW4gYiW96w1FyedF+83xG/2FNGCRpU4NjamMsn+OZ9xE5RXqdaDdPpib6RWCzuwKF9RxqI2AVNQBwQYJoK0wdBejnqtEikP3pfP51XjUTESl12FqJEKxsEorARYDD44ONTeID7YpsEnrRvQfWAI2e8WfDaTUSIwJ0iBCmFOtOUAHvVMPp/TPwvYFVYFIuP8l+DBgwdaa2Miqwa0GgYwfeMltovbDfh6c1vIgMYcliSsKv4IWFr6VDHxvldvBAH+1sA+cnl5WYOPmmr9ir+1l9I0Cgz0yjhXjfJJ0JROnmezWbl165ayr/5fqwcBNr7IfhjMqKcvESSM4eRcCasQ3bDNObmKPLdGUGpZsN24cUNLBm9zazu4d++e6qpNBFaTuUS26U5dpuR1CxyA7J9ddrMRqlz4pwLLYawymPd++/2PADt2ugcGwq9gCCdhQ96C6xWwa6j1ceuq+I0EhW0i8MAIVJfeL3d/DVD8EKi12P6/2S2jV/EccVB54O/ejz/9HGCpoBBMta5rXMXLu53D1XAwjhXwvvv+h4BAXVe4bOu3O3ChxF08LiZFG3fel199G9CH3fLyqv24NcB44MRhpdK788U3CpyKwsCw590xmfSpzsBt0Fqc3ud3vtZigxWcVZCklVpSiN0w3q5E/h9TGMIUuA3+EQAAAABJRU5ErkJggg==",S="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC"},function(e,t,n){"use strict";n.d(t,"a",function(){return l});var o=n(8),i=n.n(o),a=n(1),r=n(2),s=n(0),c=n(6),l=function(){function e(){i()(this,e),this.bDisabeCloseOnEsc=!1,this.sDefaultKeyScope=s.KeyState.None,this.sCurrentKeyScope=s.KeyState.None,this.viewModelVisibility=a.a.observable(!1),this.modalVisibility=a.a.observable(!1).extend({rateLimit:0}),this.viewModelName="",this.viewModelNames=[],this.viewModelDom=null}return e.prototype.storeAndSetKeyScope=function(){this.sCurrentKeyScope=Object(c.keyScope)(),Object(c.keyScope)(this.sDefaultKeyScope)},e.prototype.restoreKeyScope=function(){Object(c.keyScope)(this.sCurrentKeyScope)},e.prototype.registerPopupKeyDown=function(){var e=this;c.$win.on("keydown",function(t){if(t&&e.modalVisibility&&e.modalVisibility()){if(!e.bDisabeCloseOnEsc&&s.EventKeyCode.Esc===t.keyCode)return Object(r.delegateRun)(e,"cancelCommand"),!1;if(s.EventKeyCode.Backspace===t.keyCode&&!Object(r.inFocus)())return!1}return!0})},e.prototype.cancelCommand=function(){},e.prototype.closeCommand=function(){},e}()},function(e,t,n){"use strict";var o=n(8),i=n.n(o),a=n(3),r=n.n(a),s=n(1),c=n(7),l=n.n(c),u=n(5),d=function(){function e(){var t=this;i()(this,e),this.google={},this.twitter={},this.facebook={},this.dropbox={},this.google.enabled=s.a.observable(!1),this.google.clientID=s.a.observable(""),this.google.clientSecret=s.a.observable(""),this.google.apiKey=s.a.observable(""),this.google.loading=s.a.observable(!1),this.google.userName=s.a.observable(""),this.google.loggined=s.a.computed(function(){return""!==t.google.userName()}),this.google.capa={},this.google.capa.auth=s.a.observable(!1),this.google.capa.authFast=s.a.observable(!1),this.google.capa.drive=s.a.observable(!1),this.google.capa.preview=s.a.observable(!1),this.google.require={},this.google.require.clientSettings=s.a.computed(function(){return t.google.enabled()&&(t.google.capa.auth()||t.google.capa.drive())}),this.google.require.apiKeySettings=s.a.computed(function(){return t.google.enabled()&&t.google.capa.drive()}),this.facebook.enabled=s.a.observable(!1),this.facebook.appID=s.a.observable(""),this.facebook.appSecret=s.a.observable(""),this.facebook.loading=s.a.observable(!1),this.facebook.userName=s.a.observable(""),this.facebook.supported=s.a.observable(!1),this.facebook.loggined=s.a.computed(function(){return""!==t.facebook.userName()}),this.twitter.enabled=s.a.observable(!1),this.twitter.consumerKey=s.a.observable(""),this.twitter.consumerSecret=s.a.observable(""),this.twitter.loading=s.a.observable(!1),this.twitter.userName=s.a.observable(""),this.twitter.loggined=s.a.computed(function(){return""!==t.twitter.userName()}),this.dropbox.enabled=s.a.observable(!1),this.dropbox.apiKey=s.a.observable("")}return e.prototype.populate=function(){this.google.enabled(!!u.settingsGet("AllowGoogleSocial")),this.google.clientID(u.settingsGet("GoogleClientID")),this.google.clientSecret(u.settingsGet("GoogleClientSecret")),this.google.apiKey(u.settingsGet("GoogleApiKey")),this.google.capa.auth(!!u.settingsGet("AllowGoogleSocialAuth")),this.google.capa.authFast(!!u.settingsGet("AllowGoogleSocialAuthFast")),this.google.capa.drive(!!u.settingsGet("AllowGoogleSocialDrive")),this.google.capa.preview(!!u.settingsGet("AllowGoogleSocialPreview")),this.facebook.enabled(!!u.settingsGet("AllowFacebookSocial")),this.facebook.appID(u.settingsGet("FacebookAppID")),this.facebook.appSecret(u.settingsGet("FacebookAppSecret")),this.facebook.supported(!!u.settingsGet("SupportedFacebookSocial")),this.twitter.enabled=s.a.observable(!!u.settingsGet("AllowTwitterSocial")),this.twitter.consumerKey=s.a.observable(u.settingsGet("TwitterConsumerKey")),this.twitter.consumerSecret=s.a.observable(u.settingsGet("TwitterConsumerSecret")),this.dropbox.enabled(!!u.settingsGet("AllowDropboxSocial")),this.dropbox.apiKey(u.settingsGet("DropboxApiKey"))},e.prototype.appendDropbox=function(){if(!r.a.Dropbox&&this.dropbox.enabled()&&this.dropbox.apiKey()&&!r.a.document.getElementById("dropboxjs")){var e=r.a.document.createElement("script");e.type="text/javascript",e.src="https://www.dropbox.com/static/api/2/dropins.js",l()(e).attr("id","dropboxjs").attr("data-app-key",this.dropbox.apiKey()),r.a.document.body.appendChild(e)}},e}();t.a=new d},function(e,t,n){"use strict";var o=n(8),i=n.n(o),a=n(12),r=n.n(a),s=n(11),c=n.n(s),l=n(1),u=n(0),d=n(6),p=n(2),h=n(5),f=function(e){function t(){i()(this,t);var n=r()(this,e.call(this));n.currentAudio=l.a.observable(""),n.focusedState=l.a.observable(u.Focused.None);var o=h.appSettingsGet("mobile");return n.focusedState.subscribe(function(e){switch(e){case u.Focused.MessageList:Object(d.keyScope)(u.KeyState.MessageList),o&&Object(d.leftPanelDisabled)(!0);break;case u.Focused.MessageView:Object(d.keyScope)(u.KeyState.MessageView),o&&Object(d.leftPanelDisabled)(!0);break;case u.Focused.FolderList:Object(d.keyScope)(u.KeyState.FolderList),o&&Object(d.leftPanelDisabled)(!1)}}),n.projectHash=l.a.observable(""),n.threadsAllowed=l.a.observable(!1),n.composeInEdit=l.a.observable(!1),n.contactsAutosave=l.a.observable(!1),n.useLocalProxyForExternalImages=l.a.observable(!1),n.contactsIsAllowed=l.a.observable(!1),n.attachmentsActions=l.a.observableArray([]),n.devEmail="",n.devPassword="",n}return c()(t,e),t.prototype.populate=function(){e.prototype.populate.call(this),this.projectHash(h.settingsGet("ProjectHash")),this.contactsAutosave(!!h.settingsGet("ContactsAutosave")),this.useLocalProxyForExternalImages(!!h.settingsGet("UseLocalProxyForExternalImages")),this.contactsIsAllowed(!!h.settingsGet("ContactsIsAllowed"));var t=h.appSettingsGet("attachmentsActions");this.attachmentsActions(Object(p.isNonEmptyArray)(t)?t:[]),this.devEmail=h.settingsGet("DevEmail"),this.devPassword=h.settingsGet("DevPassword")},t}(n(116).a);t.a=new f},function(e,t,n){"use strict";n.d(t,"a",function(){return u}),n.d(t,"b",function(){return d});var o=n(8),i=n.n(o),a=n(7),r=n.n(a),s=n(1),c=n(2),l=n(10),u=function(){function e(){i()(this,e),this.disposable=[]}return e.prototype.dispose=function(){this.disposable.forEach(function(e){e&&e.dispose&&e.dispose()})},e}(),d=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return{template:t?{element:t}:"",viewModel:{createViewModel:function(t,n){return(t=t||{}).element=null,n&&n.element&&(t.component=n,t.element=r()(n.element),Object(l.i18nToNodes)(t.element),!Object(c.isUnd)(t.inline)&&s.a.unwrap(t.inline)&&t.element.css("display","inline-block")),new e(t)}}}}},function(e,t,n){"use strict";var o=n(8),i=n.n(o),a=n(3),r=n.n(a),s=n(1),c=n(23),l=n(0),u=n(6),d=n(2),p=n(22),h=n(5),f=function(){function e(){i()(this,e),this.iAutoLogoutTimer=0,this.layout=s.a.observable(l.Layout.SidePreview).extend({limitedList:[l.Layout.SidePreview,l.Layout.BottomPreview,l.Layout.NoPreview]}),this.editorDefaultType=s.a.observable(l.EditorDefaultType.Html).extend({limitedList:[l.EditorDefaultType.Html,l.EditorDefaultType.Plain,l.EditorDefaultType.HtmlForced,l.EditorDefaultType.PlainForced]}),this.messagesPerPage=s.a.observable(c.i).extend({limitedList:c.j}),this.showImages=s.a.observable(!1),this.useCheckboxesInList=s.a.observable(!0),this.allowDraftAutosave=s.a.observable(!0),this.useThreads=s.a.observable(!1),this.replySameFolder=s.a.observable(!1),this.autoLogout=s.a.observable(l.Magics.Time30mInMin),this.computers(),this.subscribers()}return e.prototype.computers=function(){var e=this;this.usePreviewPane=s.a.computed(function(){return l.Layout.NoPreview!==e.layout()})},e.prototype.subscribers=function(){this.layout.subscribe(function(e){u.$html.toggleClass("rl-no-preview-pane",l.Layout.NoPreview===e),u.$html.toggleClass("rl-side-preview-pane",l.Layout.SidePreview===e),u.$html.toggleClass("rl-bottom-preview-pane",l.Layout.BottomPreview===e),p.a("layout",[e])})},e.prototype.populate=function(){var e=this;this.layout(Object(d.pInt)(h.settingsGet("Layout"))),this.editorDefaultType(h.settingsGet("EditorDefaultType")),this.autoLogout(Object(d.pInt)(h.settingsGet("AutoLogout"))),this.messagesPerPage(h.settingsGet("MPP")),this.showImages(!!h.settingsGet("ShowImages")),this.useCheckboxesInList(!!h.settingsGet("UseCheckboxesInList")),this.allowDraftAutosave(!!h.settingsGet("AllowDraftAutosave")),this.useThreads(!!h.settingsGet("UseThreads")),this.replySameFolder(!!h.settingsGet("ReplySameFolder")),p.b("rl.auto-logout-refresh",function(){r.a.clearTimeout(e.iAutoLogoutTimer),01&&void 0!==arguments[1]?arguments[1]:[];Object(h.isArray)(b[e])&&p.a.each(b[e],function(e){e.apply(void 0,t)})}function a(e){return m.settingsGet(e)}function r(e,t,n,o){f.data.__APP__&&f.data.__APP__.remote().defaultRequest(e,"Plugin"+t,n,o)}function s(e,t,n,o){g.push([e,t,n,o])}function c(e,t,n,o){y.push([e,t,n,o])}function l(e){var t=n(9);p.a.each(e?y:g,function(e){t.addSettingsViewModel(e[0],e[1],e[2],e[3])})}function u(e,t){var n=m.settingsGet("Plugins");return(n=n&&!Object(h.isUnd)(n[e])?n[e]:null)?Object(h.isUnd)(n[t])?null:n[t]:null}n.d(t,"a",function(){return o}),n.d(t,"f",function(){return i}),n.d(t,"d",function(){return a}),n.d(t,"e",function(){return r}),n.d(t,"b",function(){return s}),n.d(t,"c",function(){return c}),n.d(t,"g",function(){return l}),n.d(t,"h",function(){return u});var d=n(4),p=n.n(d),h=n(2),f=n(6),m=n(5),b={},g=[],y=[]},function(e,t,n){"use strict";var o=n(8),i=n.n(o),a=n(1),r=n(4),s=n.n(r),c=n(7),l=n.n(c),u=n(10),d=n(2),p=n(31),h=n(9),f=function(){function e(){i()(this,e),this.capaOpenPGP=a.a.observable(!1),this.openpgp=null,this.openpgpkeys=a.a.observableArray([]),this.openpgpKeyring=null,this.openpgpkeysPublic=this.openpgpkeys.filter(function(e){return!(!e||e.isPrivate)}),this.openpgpkeysPrivate=this.openpgpkeys.filter(function(e){return!(!e||!e.isPrivate)})}return e.prototype.isSupported=function(){return!!this.openpgp},e.prototype.findKeyByHex=function(e,t){return s.a.find(e,function(e){return t&&e&&(t===e.id||-1').attr("title",Object(u.i18n)("MESSAGE/PGP_ENCRYPTED_MESSAGE_DESC")).on("click",e.domControlEncryptedClickHelper(this,t,s,a)):i&&(r=l()('
').attr("title",Object(u.i18n)("MESSAGE/PGP_SIGNED_MESSAGE_DESC")).on("click",e.domControlSignedClickHelper(this,t,s))),r&&t.before(r).before("
")}}},e}();t.a=new f},function(e,t,n){"use strict";var o=n(8),i=n.n(o),a=n(1),r=n(4),s=n.n(r),c=n(0),l=n(5),u=function(){function e(){i()(this,e),this.email=a.a.observable(""),this.parentEmail=a.a.observable(""),this.signature=a.a.observable(""),this.accounts=a.a.observableArray([]),this.accounts.loading=a.a.observable(!1).extend({throttle:c.Magics.Time100ms}),this.computers()}return e.prototype.computers=function(){var e=this;this.accountsEmails=a.a.computed(function(){return s.a.compact(s.a.map(e.accounts(),function(e){return e?e.email:null}))}),this.accountsUnreadCount=a.a.computed(function(){return 0})},e.prototype.populate=function(){this.email(l.settingsGet("Email")),this.parentEmail(l.settingsGet("ParentEmail"))},e.prototype.isRootAccount=function(){return""===this.parentEmail()},e}();t.a=new u},function(e,t,n){"use strict";var o=n(8),i=n.n(o),a=n(1),r=n(2),s=n(5),c=function(){function e(){i()(this,e),this.languages=a.a.observableArray([]),this.languagesAdmin=a.a.observableArray([]),this.language=a.a.observable("").extend({limitedList:this.languages}).extend({reversible:!0}),this.languageAdmin=a.a.observable("").extend({limitedList:this.languagesAdmin}).extend({reversible:!0}),this.userLanguage=a.a.observable(""),this.userLanguageAdmin=a.a.observable("")}return e.prototype.populate=function(){var e=s.appSettingsGet("languages"),t=s.appSettingsGet("languagesAdmin");this.languages(Object(r.isArray)(e)?e:[]),this.languagesAdmin(Object(r.isArray)(t)?t:[]),this.language(s.settingsGet("Language")),this.languageAdmin(s.settingsGet("LanguageAdmin")),this.userLanguage(s.settingsGet("UserLanguage")),this.userLanguageAdmin(s.settingsGet("UserLanguageAdmin"))},e}();t.a=new c},function(e,t,n){"use strict";function o(e,t){return!!v&&v.set("p"+e,t)}function i(e){return v?v.get("p"+e):null}var a=n(4),r=n.n(a),s=n(8),c=n.n(s),l=n(3),u=n.n(l),d=n(120),p=n.n(d),h=n(2),f=n(23),m=function(){function e(){c()(this,e)}return e.prototype.set=function(e,t){var n=!1,o=null;try{o=p.a.getJSON(f.b)}catch(e){}(o||(o={}))[e]=t;try{p.a.set(f.b,o,{expires:30}),n=!0}catch(e){}return n},e.prototype.get=function(e){var t=null;try{var n=p.a.getJSON(f.b);t=n&&!Object(h.isUnd)(n[e])?n[e]:null}catch(e){}return t},e.supported=function(){return!(!u.a.navigator||!u.a.navigator.cookieEnabled)},e}(),b=n(69),g=function(){function e(){c()(this,e),this.s=null,this.s=u.a.localStorage||null}return e.prototype.set=function(e,t){if(!this.s)return!1;var n=null;try{var o=this.s.getItem(f.b)||null;n=null===o?null:u.a.JSON.parse(o)}catch(e){}(n||(n={}))[e]=t;try{return this.s.setItem(f.b,u.a.JSON.stringify(n)),!0}catch(e){}return!1},e.prototype.get=function(e){if(!this.s)return null;try{var t=this.s.getItem(f.b)||null,n=null===t?null:u.a.JSON.parse(t);return n&&!Object(h.isUnd)(n[e])?n[e]:null}catch(e){}return null},e.supported=function(){return Object(b.d)("localStorage")},e}();n.d(t,"b",function(){return o}),n.d(t,"a",function(){return i});var y=r.a.find([g,m],function(e){return e&&e.supported()}),v=y?new y:null},function(e,t,n){"use strict";function o(){return S(),y||b()()}function i(){return O(),v||0}function a(e){return o().clone().subtract(e,"days").format("YYYY.MM.DD")}function r(e,t){var n=null,a="",r=i();if((n=0<(e=r<(e=0=t.diff(e,"hours"):return e.fromNow();case t.format("L")===e.format("L"):return Object(g.i18n)("MESSAGE_LIST/TODAY_AT",{TIME:e.format("LT")});case t.clone().subtract(1,"days").format("L")===e.format("L"):return Object(g.i18n)("MESSAGE_LIST/YESTERDAY_AT",{TIME:e.format("LT")});case t.year()===e.year():return e.format("D MMM.")}return e?e.format("LL"):""}(n);break;case"FULL":a=n.format("LLL");break;default:a=n.format(t)}return a}function s(e){var t,n="",o=f()(e);(t=o.data("moment-time"))&&((n=o.data("moment-format"))&&o.text(r(t,n)),(n=o.data("moment-format-title"))&&o.attr("title",r(t,n)))}function c(){p.a.defer(function(){f()(".moment",u.a.document).each(function(e,t){s(t)})})}n.r(t),n.d(t,"momentNow",function(){return o}),n.d(t,"momentNowUnix",function(){return i}),n.d(t,"searchSubtractFormatDateHelper",function(){return a}),n.d(t,"format",function(){return r}),n.d(t,"momentToNode",function(){return s}),n.d(t,"reload",function(){return c});var l=n(3),u=n.n(l),d=n(4),p=n.n(d),h=n(7),f=n.n(h),m=n(54),b=n.n(m),g=n(10),y=null,v=0,S=p.a.debounce(function(){y=b()()},500,!0),O=p.a.debounce(function(){v=b()().unix()},500,!0)},function(e,t){e.exports=window.hasher},function(e,t,n){"use strict";n.d(t,"a",function(){return r});var o=n(8),i=n.n(o),a=n(2),r=function(){function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";i()(this,e),this.sModelName="",this.disposables=[],this.sModelName=t||""}return e.prototype.regDisposables=function(e){var t=this;Object(a.isArray)(e)?e.forEach(function(e){t.disposables.push(e)}):e&&this.disposables.push(e)},e.prototype.onDestroy=function(){Object(a.disposeObject)(this)},e}()},,,function(e,t,n){"use strict";var o=n(8),i=n.n(o),a=n(1),r=n(2),s=n(5),c=function(){function e(){i()(this,e),this.themes=a.a.observableArray([]),this.themeBackgroundName=a.a.observable(""),this.themeBackgroundHash=a.a.observable(""),this.theme=a.a.observable("").extend({limitedList:this.themes})}return e.prototype.populate=function(){var e=s.appSettingsGet("themes");this.themes(Object(r.isArray)(e)?e:[]),this.theme(s.settingsGet("Theme")),this.themeBackgroundName(s.settingsGet("UserBackgroundName")),this.themeBackgroundHash(s.settingsGet("UserBackgroundHash"))},e}();t.a=new c},function(e,t){var n=e.exports={version:"2.5.1"};"number"==typeof __e&&(__e=n)},function(e,t){var n=e.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=n)},function(e,t,n){e.exports=!n(51)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(e,t,n){var o=n(109),i=n(73);e.exports=function(e){return o(i(e))}},function(e,t,n){"use strict";n.r(t),n.d(t,"EmailModel",function(){return u}),n.d(t,"default",function(){return u});var o=n(8),i=n.n(o),a=n(4),r=n.n(a),s=n(76),c=n.n(s),l=n(2),u=function(){function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"none",a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"";i()(this,e),this.email="",this.name="",this.dkimStatus="",this.dkimValue="",this.email=t,this.name=n,this.dkimStatus=o,this.dkimValue=a,this.clearDuplicateName()}return e.newInstanceFromJson=function(t){var n=new e;return n.initByJson(t)?n:null},e.prototype.clear=function(){this.email="",this.name="",this.dkimStatus="none",this.dkimValue=""},e.prototype.validate=function(){return""!==this.name||""!==this.email},e.prototype.hash=function(){return"#"+(arguments.length>0&&void 0!==arguments[0]&&arguments[0]?"":this.name)+"#"+this.email+"#"},e.prototype.clearDuplicateName=function(){this.name===this.email&&(this.name="")},e.prototype.search=function(e){return-1<(this.name+" "+this.email).toLowerCase().indexOf(e.toLowerCase())},e.prototype.initByJson=function(e){var t=!1;return e&&"Object/Email"===e["@Object"]&&(this.name=Object(l.trim)(e.Name),this.email=Object(l.trim)(e.Email),this.dkimStatus=Object(l.trim)(e.DkimStatus||""),this.dkimValue=Object(l.trim)(e.DkimValue||""),t=""!==this.email,this.clearDuplicateName()),t},e.prototype.toLine=function(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],o="";return""!==this.email&&(e&&""!==this.name?o=t?'
")+'" target="_blank" tabindex="-1">'+Object(l.encodeHtml)(this.name)+"":n?Object(l.encodeHtml)(this.name):this.name:(o=this.email,""!==this.name?t?o=Object(l.encodeHtml)('"'+this.name+'" <')+'")+'" target="_blank" tabindex="-1">'+Object(l.encodeHtml)(o)+""+Object(l.encodeHtml)(">"):(o='"'+this.name+'" <'+o+">",n&&(o=Object(l.encodeHtml)(o))):t&&(o=''+Object(l.encodeHtml)(this.email)+""))),o},e.splitEmailLine=function(t){var n=c()(t);if(Object(l.isNonEmptyArray)(n)){var o=[],i=!1;return n.forEach(function(t){var n=t.address?new e(t.address.replace(/^[<]+(.*)[>]+$/g,"$1"),t.name||""):null;n&&n.email&&(i=!0),o.push(n?n.toLine(!1):t.name)}),i?o:null}return null},e.parseEmailLine=function(t){var n=c()(t);return Object(l.isNonEmptyArray)(n)?r.a.compact(n.map(function(t){return t.address?new e(t.address.replace(/^[<]+(.*)[>]+$/g,"$1"),t.name||""):null})):[]},e.prototype.parse=function(e){if(""===(e=Object(l.trim)(e)))return!1;var t=c()(e);return!(!Object(l.isNonEmptyArray)(t)||!t[0]||(this.name=t[0].name||"",this.email=t[0].address||"",this.clearDuplicateName(),0))},e}()},function(e,t,n){"use strict";var o=n(8),i=n.n(o),a=n(3),r=n.n(a),s=n(6),c=n(16),l=n(22),u=n(2),d=function(){function e(){var t=this;if(i()(this,e),this.notificator=null,this.player=null,this.supported=!1,this.supportedMp3=!1,this.supportedOgg=!1,this.supportedWav=!1,this.supportedNotification=!1,this.player=this.createNewObject(),this.supported=!(s.bMobileDevice||s.bSafari||!this.player||!this.player.play),this.supported&&this.player&&this.player.canPlayType&&(this.supportedMp3=""!==this.player.canPlayType("audio/mpeg;").replace(/no/,""),this.supportedWav=""!==this.player.canPlayType('audio/wav; codecs="1"').replace(/no/,""),this.supportedOgg=""!==this.player.canPlayType('audio/ogg; codecs="vorbis"').replace(/no/,""),this.supportedNotification=this.supported&&this.supportedMp3),this.player&&(this.supportedMp3||this.supportedOgg||this.supportedWav)||(this.supported=!1,this.supportedMp3=!1,this.supportedOgg=!1,this.supportedWav=!1,this.supportedNotification=!1),this.supported&&this.player){var n=function(){return t.stop()};this.player.addEventListener("ended",n),this.player.addEventListener("error",n),l.b("audio.api.stop",n)}}return e.prototype.createNewObject=function(){var e=r.a.Audio?new r.a.Audio:null;return e&&e.canPlayType&&e.pause&&e.play&&(e.preload="none",e.loop=!1,e.autoplay=!1,e.muted=!1),e},e.prototype.paused=function(){return!this.supported||!!this.player.paused},e.prototype.stop=function(){this.supported&&this.player.pause&&this.player.pause(),l.a("audio.stop")},e.prototype.pause=function(){this.stop()},e.prototype.clearName=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return e=Object(u.trim)(e),t&&"."+t===e.toLowerCase().substr(-1*(t.length+1))&&(e=Object(u.trim)(e.substr(0,e.length-4))),""===e?"audio":e},e.prototype.playMp3=function(e,t){this.supported&&this.supportedMp3&&(this.player.src=e,this.player.play(),l.a("audio.start",[this.clearName(t,"mp3"),"mp3"]))},e.prototype.playOgg=function(e,t){this.supported&&this.supportedOgg&&(this.player.src=e,this.player.play(),t=this.clearName(t,"oga"),t=this.clearName(t,"ogg"),l.a("audio.start",[t,"ogg"]))},e.prototype.playWav=function(e,t){this.supported&&this.supportedWav&&(this.player.src=e,this.player.play(),l.a("audio.start",[this.clearName(t,"wav"),"wav"]))},e.prototype.playNotification=function(){this.supported&&this.supportedMp3&&(this.notificator||(this.notificator=this.createNewObject(),this.notificator.src=c.D("new-mail.mp3")),this.notificator&&this.notificator.play&&this.notificator.play())},e}();t.a=new d},function(e,t){var n={}.hasOwnProperty;e.exports=function(e,t){return n.call(e,t)}},function(e,t,n){"use strict";n.d(t,"a",function(){return p});var o=n(8),i=n.n(o),a=n(12),r=n.n(a),s=n(11),c=n.n(s),l=n(1),u=n(2),d=n(0),p=function(e){function t(n){i()(this,t);var o=r()(this,e.call(this));return o.value=n.value||"",o.size=n.size||0,o.label=n.label||"",o.preLabel=n.preLabel||"",o.enable=!!Object(u.isUnd)(n.enable)||n.enable,o.trigger=n.trigger&&n.trigger.subscribe?n.trigger:null,o.placeholder=n.placeholder||"",o.labeled=!Object(u.isUnd)(n.label),o.preLabeled=!Object(u.isUnd)(n.preLabel),o.triggered=!Object(u.isUnd)(n.trigger)&&!!o.trigger,o.classForTrigger=l.a.observable(""),o.className=l.a.computed(function(){var e=l.a.unwrap(o.size),t=o.trigger?" "+Object(u.trim)("settings-saved-trigger-input "+o.classForTrigger()):"";return(0o?10:o,S.a.displaySpecSetting(0>=n||oObject(f.microtime)()-l);var d="";switch(!0){case"success"===n&&t&&t.Result&&e===t.Action:d=m.StorageResultType.Success;break;case!("abort"!==n||t&&t.__aborted__):d=m.StorageResultType.Abort;break;default:d=m.StorageResultType.Error}L.f("ajax-default-response",[e,m.StorageResultType.Success===d?t:null,d,i,o]),"success"===n?t&&t.Result&&e===t.Action?(t.__cached__=i,s(t)):t&&t.Action?(u=t,c(t.ErrorCode?t.ErrorCode:m.Notification.AjaxFalse)):(u=t,c(m.Notification.AjaxParse)):"timeout"===n?(u=t,c(m.Notification.AjaxTimeout)):"abort"===n?t&&t.__aborted__||c(m.Notification.AjaxAbort):(u=t,c(m.Notification.AjaxParse)),r.oRequests[e]&&(r.oRequests[e]=null,delete r.oRequests[e]),r.setTrigger(a,!1),u&&(-11&&void 0!==arguments[1]&&arguments[1];if(!a.a.Promise||!a.a.Promise.all)throw new Error("Promises are not available your environment.");if(!e)throw new Error("src should not be empty.");return new a.a.Promise(function(n,o){var i=a.a.document.createElement("script");i.onload=function(){n(e)},i.onerror=function(){o(new Error(e))},i.async=!0===t,i.src=e,a.a.document.body.appendChild(i)})}n.d(t,"a",function(){return o});var i=n(3),a=n.n(i)},function(e,t,n){var o=n(85)("wks"),i=n(70),a=n(41).Symbol,r="function"==typeof a;(e.exports=function(e){return o[e]||(o[e]=r&&a[e]||(r?a:i)("Symbol."+e))}).store=o},function(e,t,n){var o=n(52);e.exports=function(e){if(!o(e))throw TypeError(e+" is not an object!");return e}},function(e,t,n){"use strict";var o=n(8),i=n.n(o),a=n(3),r=n.n(a),s=n(1),c=n(0),l=n(22),u=n(45),d=n(5),p=function(){function e(){var t=this;i()(this,e),this.enableSoundNotification=s.a.observable(!1),this.soundNotificationIsSupported=s.a.observable(!1),this.allowDesktopNotification=s.a.observable(!1),this.desktopNotificationPermissions=s.a.computed(function(){t.allowDesktopNotification();var e=c.DesktopNotification.NotSupported,n=t.notificationClass();if(n&&n.permission)switch(n.permission.toLowerCase()){case"granted":e=c.DesktopNotification.Allowed;break;case"denied":e=c.DesktopNotification.Denied;break;case"default":e=c.DesktopNotification.NotAllowed}else r.a.webkitNotifications&&r.a.webkitNotifications.checkPermission&&(e=r.a.webkitNotifications.checkPermission());return e}).extend({notify:"always"}),this.enableDesktopNotification=s.a.computed({read:function(){return t.allowDesktopNotification()&&c.DesktopNotification.Allowed===t.desktopNotificationPermissions()},write:function(e){if(e){var n=t.notificationClass(),o=t.desktopNotificationPermissions();n&&c.DesktopNotification.Allowed===o?t.allowDesktopNotification(!0):n&&c.DesktopNotification.NotAllowed===o?n.requestPermission(function(){t.allowDesktopNotification.valueHasMutated(),c.DesktopNotification.Allowed===t.desktopNotificationPermissions()?t.allowDesktopNotification()?t.allowDesktopNotification.valueHasMutated():t.allowDesktopNotification(!0):t.allowDesktopNotification()?t.allowDesktopNotification(!1):t.allowDesktopNotification.valueHasMutated()}):t.allowDesktopNotification(!1)}else t.allowDesktopNotification(!1)}}).extend({notify:"always"}),this.enableDesktopNotification.valueHasMutated||(this.enableDesktopNotification.valueHasMutated=function(){t.allowDesktopNotification.valueHasMutated()}),this.computers(),this.initNotificationPlayer()}return e.prototype.computers=function(){var e=this;this.isDesktopNotificationSupported=s.a.computed(function(){return c.DesktopNotification.NotSupported!==e.desktopNotificationPermissions()}),this.isDesktopNotificationDenied=s.a.computed(function(){return c.DesktopNotification.NotSupported===e.desktopNotificationPermissions()||c.DesktopNotification.Denied===e.desktopNotificationPermissions()})},e.prototype.initNotificationPlayer=function(){u.a&&u.a.supportedNotification?this.soundNotificationIsSupported(!0):(this.enableSoundNotification(!1),this.soundNotificationIsSupported(!1))},e.prototype.playSoundNotification=function(e){u.a&&u.a.supportedNotification&&(e||this.enableSoundNotification())&&u.a.playNotification()},e.prototype.displayDesktopNotification=function(e,t,n,o){if(this.enableDesktopNotification()){var i=this.notificationClass(),a=i?new i(t,{body:n,icon:e}):null;a&&(a.show&&a.show(),o&&(a.onclick=function(){r.a.focus(),o.Folder&&o.Uid&&l.a("mailbox.message.show",[o.Folder,o.Uid])}),r.a.setTimeout((s=a,function(){s.cancel?s.cancel():s.close&&s.close()}),c.Magics.Time7s))}var s},e.prototype.populate=function(){this.enableSoundNotification(!!d.settingsGet("SoundNotification")),this.enableDesktopNotification(!!d.settingsGet("DesktopNotifications"))},e.prototype.notificationClass=function(){return r.a.Notification&&r.a.Notification.requestPermission?r.a.Notification:null},e}();t.a=new p},function(e,t,n){"use strict";function o(e,t,n,o,i){var a={};return Object.keys(o).forEach(function(e){a[e]=o[e]}),a.enumerable=!!a.enumerable,a.configurable=!!a.configurable,("value"in a||a.initializer)&&(a.writable=!0),a=n.slice().reverse().reduce(function(n,o){return o(e,t,n)||n},a),i&&void 0!==a.initializer&&(a.value=a.initializer?a.initializer.call(i):void 0,a.initializer=void 0),void 0===a.initializer&&(Object.defineProperty(e,t,a),a=null),a}n.r(t);var i,a,r,s,c,l,u,d,p,h,f=n(18),m=n.n(f),b=n(8),g=n.n(b),y=n(12),v=n.n(y),S=n(11),O=n.n(S),w=n(3),T=n.n(w),C=n(4),A=n.n(C),E=n(7),F=n.n(E),j=n(1),N=n(19),R=n.n(N),I=n(78),L=n.n(I),_=n(0),P=n(2),D=n(23),M=n(6),k=n(16),x=n(10),U=n(34),H=n(15),B=n(95),G=n(26),K=n(28),V=n(56),z=n(31),q=n(13),W=n(30),Y=n(14),$=n(25),J=n(17),X=n(5),Z=n(22),Q=n(79),ee=function(e){function t(n,o){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,a=arguments.length>3&&void 0!==arguments[3]&&arguments[3],r=arguments.length>4&&void 0!==arguments[4]&&arguments[4],s=arguments.length>5&&void 0!==arguments[5]?arguments[5]:"",c=arguments.length>6&&void 0!==arguments[6]?arguments[6]:"";g()(this,t);var l=v()(this,e.call(this,"ComposeAttachmentModel"));return l.id=n,l.isInline=!!a,l.isLinked=!!r,l.CID=s,l.contentLocation=c,l.fromMessage=!1,l.fileName=j.a.observable(o),l.size=j.a.observable(i),l.tempName=j.a.observable(""),l.progress=j.a.observable(0),l.error=j.a.observable(""),l.waiting=j.a.observable(!0),l.uploading=j.a.observable(!1),l.enabled=j.a.observable(!0),l.complete=j.a.observable(!1),l.progressText=j.a.computed(function(){var e=l.progress();return 0===e?"":(98a[e.email][1])&&(o=a[e.email][0],n=a[e.email][1])};if(A.a.each(i,function(e,t){a[e.email()]=[e,t]}),t)switch(e){case _.ComposeType.Empty:break;case _.ComposeType.Reply:case _.ComposeType.ReplyAll:case _.ComposeType.Forward:case _.ComposeType.ForwardAsAttachment:A.a.each(A.a.union(t.to,t.cc,t.bcc),r),o||A.a.each(t.deliveredTo,r);break;case _.ComposeType.Draft:A.a.each(A.a.union(t.from,t.replyTo),r)}return o||i[0]||null},t.prototype.selectIdentity=function(e){e&&e.item&&(this.currentIdentity(e.item),this.setSignatureFromIdentity(e.item))},t.prototype.sendMessageResponse=function(e,t){var n=!1,o="";this.sending(!1),_.StorageResultType.Success===e&&t&&t.Result&&(n=!0,this.modalVisibility()&&Object(P.delegateRun)(this,"closeCommand")),this.modalVisibility()&&!n&&(t&&_.Notification.CantSaveMessage===t.ErrorCode?(this.sendSuccessButSaveError(!0),this.savedErrorDesc(Object(P.trim)(Object(x.i18n)("COMPOSE/SAVED_ERROR_ON_SEND")))):(o=Object(x.getNotification)(t&&t.ErrorCode?t.ErrorCode:_.Notification.CantSendMessage,t&&t.ErrorMessage?t.ErrorMessage:""),this.sendError(!0),this.sendErrorDesc(o||Object(x.getNotification)(_.Notification.CantSendMessage)))),this.reloadDraftFolder()},t.prototype.saveMessageResponse=function(e,t){var n=!1;if(this.saving(!1),_.StorageResultType.Success===e&&t&&t.Result&&t.Result.NewFolder&&t.Result.NewUid){if(n=!0,this.bFromDraft){var o=Y.a.message();o&&this.draftFolder()===o.folderFullNameRaw&&this.draftUid()===o.uid&&Y.a.message(null)}this.draftFolder(t.Result.NewFolder),this.draftUid(t.Result.NewUid),this.savedTime(T.a.Math.round((new T.a.Date).getTime()/1e3)),this.bFromDraft&&Object(H.q)(this.draftFolder(),"")}n||(this.savedError(!0),this.savedErrorDesc(Object(x.getNotification)(_.Notification.CantSaveMessage))),this.reloadDraftFolder()},t.prototype.onHide=function(){this.autosaveStop(),this.bSkipNextHide||(G.a.composeInEdit(!1),this.reset()),this.bSkipNextHide=!1,this.to.focused(!1),Object(ne.routeOn)()},t.prototype.editor=function(e){var t=this;e&&(!this.oEditor&&this.composeEditorArea()?this.oEditor=new B.HtmlEditor(this.composeEditorArea(),null,function(){e(t.oEditor),t.resizerTrigger()},function(e){t.isHtml(!!e)}):this.oEditor&&(e(this.oEditor),this.resizerTrigger()))},t.prototype.converSignature=function(e){var t=10,n="",o=[],i=/{{MOMENT:([^}]+)}}/g;if(e=e.replace(/[\r]/g,""),""!==(n=this.oLastMessage?this.emailArrayToStringLineHelper(this.oLastMessage.from,!0):"")&&(e=e.replace(/{{FROM-FULL}}/g,n),-1===n.indexOf(" ")&&0
"+f+":

"+Object(P.trim)(h)+"
";break;case _.ComposeType.Forward:c=g.fromToLine(!1,!0),l=g.toToLine(!1,!0),u=g.ccToLine(!1,!0),h="

"+Object(x.i18n)("COMPOSE/FORWARD_MESSAGE_TOP_TITLE")+"
"+Object(x.i18n)("COMPOSE/FORWARD_MESSAGE_TOP_FROM")+": "+c+"
"+Object(x.i18n)("COMPOSE/FORWARD_MESSAGE_TOP_TO")+": "+l+(0"+Object(x.i18n)("COMPOSE/FORWARD_MESSAGE_TOP_CC")+": "+u:"")+"
"+Object(x.i18n)("COMPOSE/FORWARD_MESSAGE_TOP_SENT")+": "+Object(P.encodeHtml)(d)+"
"+Object(x.i18n)("COMPOSE/FORWARD_MESSAGE_TOP_SUBJECT")+": "+Object(P.encodeHtml)(p)+"

"+Object(P.trim)(h)+"

";break;case _.ComposeType.ForwardAsAttachment:h=""}this.editor(function(e){e.setHtml(h,!1),(_.EditorDefaultType.PlainForced===s.editorDefaultType()||!g.isHtml()&&_.EditorDefaultType.HtmlForced!==s.editorDefaultType())&&e.modeToggle(!1),m&&_.ComposeType.Draft!==S&&_.ComposeType.EditAsNew!==S&&s.setSignatureFromIdentity(m),s.setFocusInPopup()})}else _.ComposeType.Empty===S?(this.subject(Object(P.isNormal)(a)?""+a:""),h=Object(P.isNormal)(r)?""+r:"",this.editor(function(e){e.setHtml(h,!1),_.EditorDefaultType.Html!==s.editorDefaultType()&&_.EditorDefaultType.HtmlForced!==s.editorDefaultType()&&e.modeToggle(!1),m&&s.setSignatureFromIdentity(m),s.setFocusInPopup()})):Object(P.isNonEmptyArray)(t)?(A.a.each(t,function(e){s.addMessageAsAttachment(e)}),this.editor(function(e){e.setHtml("",!1),_.EditorDefaultType.Html!==s.editorDefaultType()&&_.EditorDefaultType.HtmlForced!==s.editorDefaultType()&&e.modeToggle(!1),m&&_.ComposeType.Draft!==S&&_.ComposeType.EditAsNew!==S&&s.setSignatureFromIdentity(m),s.setFocusInPopup()})):this.setFocusInPopup();var T=this.getAttachmentsDownloadsForUpload();Object(P.isNonEmptyArray)(T)&&J.a.messageUploadAttachments(this.onMessageUploadAttachments,T),m&&this.currentIdentity(m),this.resizerTrigger()},t.prototype.onMessageUploadAttachments=function(e,t){var n=this;_.StorageResultType.Success===e&&t&&t.Result?this.viewModelVisibility()||A.a.each(t.Result,function(e,t){var o=n.getAttachmentById(e);o&&(o.tempName(t),o.waiting(!1).uploading(!1).complete(!0))}):this.setMessageAttachmentFailedDownloadText()},t.prototype.setFocusInPopup=function(){var e=this;M.bMobileDevice||A.a.delay(function(){""===e.to()?e.to.focused(!0):e.oEditor&&(e.to.focused()||e.oEditor.focus())},_.Magics.Time100ms)},t.prototype.onShowWithDelay=function(){this.resizerTrigger()},t.prototype.tryToClosePopup=function(){var e=this,t=n(99);!Object(ne.isPopupVisible)(t)&&this.modalVisibility()&&(this.bSkipNextHide||this.isEmptyForm()&&!this.draftUid()?Object(P.delegateRun)(this,"closeCommand"):Object(ne.showScreenPopup)(t,[Object(x.i18n)("POPUPS_ASK/DESC_WANT_CLOSE_THIS_WINDOW"),function(){e.modalVisibility()&&Object(P.delegateRun)(e,"closeCommand")}]))},t.prototype.onBuild=function(){var e=this;this.initUploader(),R()("ctrl+q, command+q, ctrl+w, command+w",_.KeyState.Compose,P.noopFalse),R()("`",_.KeyState.Compose,function(){return!(e.oEditor&&!e.oEditor.hasFocus()&&!Object(P.inFocus)()&&(e.identitiesDropdownTrigger(!0),1))}),R()("ctrl+`",_.KeyState.Compose,function(){return e.identitiesDropdownTrigger(!0),!1}),R()("esc, ctrl+down, command+down",_.KeyState.Compose,function(){return e.skipCommand(),!1}),this.allowFolders&&R()("ctrl+s, command+s",_.KeyState.Compose,function(){return e.saveCommand(),!1}),X.appSettingsGet("allowCtrlEnterOnCompose")&&R()("ctrl+enter, command+enter",_.KeyState.Compose,function(){return e.sendCommand(),!1}),R()("shift+esc",_.KeyState.Compose,function(){return e.modalVisibility()&&e.tryToClosePopup(),!1}),Z.b("window.resize.real",this.resizerTrigger),Z.b("window.resize.real",A.a.debounce(this.resizerTrigger,_.Magics.Time50ms)),$.a.appendDropbox(),this.driveEnabled()&&F.a.getScript("https://apis.google.com/js/api.js",function(){T.a.gapi&&e.driveVisible(!0)}),T.a.setInterval(function(){e.modalVisibility()&&e.oEditor&&e.oEditor.resize()},_.Magics.Time5s)},t.prototype.driveCallback=function(e,t){var n=this;if(t&&T.a.XMLHttpRequest&&T.a.google&&t[T.a.google.picker.Response.ACTION]===T.a.google.picker.Action.PICKED&&t[T.a.google.picker.Response.DOCUMENTS]&&t[T.a.google.picker.Response.DOCUMENTS][0]&&t[T.a.google.picker.Response.DOCUMENTS][0].id){var o=new T.a.XMLHttpRequest;o.open("GET","https://www.googleapis.com/drive/v2/files/"+t[T.a.google.picker.Response.DOCUMENTS][0].id),o.setRequestHeader("Authorization","Bearer "+e),o.addEventListener("load",function(){if(o&&o.responseText){var t=T.a.JSON.parse(o.responseText),i=function(e,n,o){e&&e.exportLinks&&(e.exportLinks[n]?(t.downloadUrl=e.exportLinks[n],t.title=e.title+"."+o,t.mimeType=n):e.exportLinks["application/pdf"]&&(t.downloadUrl=e.exportLinks["application/pdf"],t.title=e.title+".pdf",t.mimeType="application/pdf"))};if(t&&!t.downloadUrl&&t.mimeType&&t.exportLinks)switch(t.mimeType.toString().toLowerCase()){case"application/vnd.google-apps.document":i(t,"application/vnd.openxmlformats-officedocument.wordprocessingml.document","docx");break;case"application/vnd.google-apps.spreadsheet":i(t,"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","xlsx");break;case"application/vnd.google-apps.drawing":i(t,"image/png","png");break;case"application/vnd.google-apps.presentation":i(t,"application/vnd.openxmlformats-officedocument.presentationml.presentation","pptx");break;default:i(t,"application/pdf","pdf")}t&&t.downloadUrl&&n.addDriveAttachment(t,e)}}),o.send()}},t.prototype.driveCreatePiker=function(e){var t=this;T.a.gapi&&e&&e.access_token&&T.a.gapi.load("picker",{callback:function(){T.a.google&&T.a.google.picker&&(new T.a.google.picker.PickerBuilder).addView(T.a.google.picker.ViewId.DOCS).setAppId(X.settingsGet("GoogleClientID")).setOAuthToken(e.access_token).setCallback(A.a.bind(t.driveCallback,t,e.access_token)).enableFeature(T.a.google.picker.Feature.NAV_HIDDEN).build().setVisible(!0)}})},t.prototype.driveOpenPopup=function(){var e=this;T.a.gapi&&T.a.gapi.load("auth",{callback:function(){var t=T.a.gapi.auth.getToken(),n=function(t){if(t&&!t.error){var n=T.a.gapi.auth.getToken();return n&&e.driveCreatePiker(n),!0}return!1};t?e.driveCreatePiker(t):T.a.gapi.auth.authorize({client_id:X.settingsGet("GoogleClientID"),scope:"https://www.googleapis.com/auth/drive.readonly",immediate:!0},function(e){n(e)||T.a.gapi.auth.authorize({client_id:X.settingsGet("GoogleClientID"),scope:"https://www.googleapis.com/auth/drive.readonly",immediate:!1},n)})}})},t.prototype.getAttachmentById=function(e){return A.a.find(this.attachments(),function(t){return t&&e===t.id})},t.prototype.cancelAttachmentHelper=function(e,t){var n=this;return function(){var o=A.a.find(n.attachments(),function(t){return t&&t.id===e});o&&(n.attachments.remove(o),Object(P.delegateRunOnDestroy)(o),t&&t.cancel(e))}},t.prototype.initUploader=function(){var e=this;if(this.composeUploaderButton()){var t={},n=Object(P.pInt)(X.settingsGet("AttachmentLimit")),o=new L.a({action:Object(k.G)(),name:"uploader",queueSize:2,multipleSizeLimit:50,clickElement:this.composeUploaderButton(),dragAndDropElement:this.composeUploaderDropPlace()});o?(o.on("onDragEnter",function(){e.dragAndDropOver(!0)}).on("onDragLeave",function(){e.dragAndDropOver(!1)}).on("onBodyDragEnter",function(){e.attachmentsPlace(!0),e.dragAndDropVisible(!0)}).on("onBodyDragLeave",function(){e.dragAndDropVisible(!1)}).on("onProgress",function(n,o,i){var a=t[n];a||(a=e.getAttachmentById(n))&&(t[n]=a),a&&a.progress(T.a.Math.floor(o/i*100))}).on("onSelect",function(t,i){e.dragAndDropOver(!1);var a=Object(P.isUnd)(i.FileName)?"":i.FileName.toString(),r=Object(P.isNormal)(i.Size)?Object(P.pInt)(i.Size):null,s=new ee(t,a,r);return s.cancel=e.cancelAttachmentHelper(t,o),e.attachments.push(s),e.attachmentsPlace(!0),!(00&&void 0!==arguments[0]&&!arguments[0]?0===this.attachmentsInReady().length:0===this.attachments().length;return 0===this.to().length&&0===this.cc().length&&0===this.bcc().length&&0===this.replyTo().length&&0===this.subject().length&&e&&(!this.oEditor||""===this.oEditor.getData())},t.prototype.reset=function(){this.to(""),this.cc(""),this.bcc(""),this.replyTo(""),this.subject(""),this.requestDsn(!1),this.requestReadReceipt(!1),this.markAsImportant(!1),this.attachmentsPlace(!1),this.aDraftInfo=null,this.sInReplyTo="",this.bFromDraft=!1,this.sReferences="",this.sendError(!1),this.sendSuccessButSaveError(!1),this.savedError(!1),this.savedTime(0),this.emptyToError(!1),this.attachmentsInProcessError(!1),this.showCc(!1),this.showBcc(!1),this.showReplyTo(!1),Object(P.delegateRunOnDestroy)(this.attachments()),this.attachments([]),this.dragAndDropOver(!1),this.dragAndDropVisible(!1),this.draftFolder(""),this.draftUid(""),this.sending(!1),this.saving(!1),this.oEditor&&this.oEditor.clear(!1)},t.prototype.getAttachmentsDownloadsForUpload=function(){return A.a.map(A.a.filter(this.attachments(),function(e){return e&&""===e.tempName()}),function(e){return e.id})},t.prototype.resizerTrigger=function(){this.resizer(!this.resizer())},t}(oe.a)).prototype,"sendCommand",[a],m()(h.prototype,"sendCommand"),h.prototype),o(h.prototype,"saveCommand",[r],m()(h.prototype,"saveCommand"),h.prototype),o(h.prototype,"deleteCommand",[s],m()(h.prototype,"deleteCommand"),h.prototype),o(h.prototype,"skipCommand",[c],m()(h.prototype,"skipCommand"),h.prototype),o(h.prototype,"contactsCommand",[l],m()(h.prototype,"contactsCommand"),h.prototype),o(h.prototype,"dropboxCommand",[u],m()(h.prototype,"dropboxCommand"),h.prototype),o(h.prototype,"driveCommand",[d],m()(h.prototype,"driveCommand"),h.prototype),p=h))||p)},function(e,t){e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},function(e,t,n){"use strict";n.d(t,"a",function(){return u});var o=n(8),i=n.n(o),a=n(4),r=n.n(a),s=n(75),c=n.n(s),l=n(2),u=function(){function e(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];i()(this,e),this.oCross=null,this.sScreenName=t,this.aViewModels=Object(l.isArray)(n)?n:[]}return e.prototype.viewModels=function(){return this.aViewModels},e.prototype.screenName=function(){return this.sScreenName},e.prototype.routes=function(){return null},e.prototype.__cross=function(){return this.oCross},e.prototype.__start=function(){var e=null,t=null,n=this.routes();Object(l.isNonEmptyArray)(n)&&(t=r.a.bind(this.onRoute||l.noop,this),e=c.a.create(),n.forEach(function(n){n&&e&&(e.addRoute(n[0],t).rules=n[1])}),this.oCross=e)},e}()},function(e,t){e.exports=window.ssm},function(e,t,n){var o=n(52);e.exports=function(e,t){if(!o(e))return e;var n,i;if(t&&"function"==typeof(n=e.toString)&&!o(i=n.call(e)))return i;if("function"==typeof(n=e.valueOf)&&!o(i=n.call(e)))return i;if(!t&&"function"==typeof(n=e.toString)&&!o(i=n.call(e)))return i;throw TypeError("Can't convert object to primitive value")}},,function(e,t,n){"use strict";function o(e){if(e in l.a&&l.a[e]&&l.a[e].setItem){var t=l.a[e],n="testLocalStorage_"+l.a.Math.random();try{if(t.setItem(n,n),n===t.getItem(n))return t.removeItem(n),!0}catch(e){}}return!1}function i(){return h(u)}function a(){var e="AuthAccountHash",t=l.a.__rlah_data();f(u,t&&t[e]?t[e]:""),b()}function r(){f(u,""),b()}function s(){return m()>g()+36e5&&(r(),!0)}n.d(t,"d",function(){return o}),n.d(t,"c",function(){return i}),n.d(t,"e",function(){return a}),n.d(t,"b",function(){return r}),n.d(t,"a",function(){return s});var c=n(3),l=n.n(c),u="__rlA",d=o("sessionStorage")&&l.a.sessionStorage||null,p=l.a.top||l.a||null,h=function(e){var t=null;if(d)t=d.getItem(e)||null;else if(p&&l.a.JSON){var n=p.name&&"{"===p.name.toString().substr(0,1)?l.a.JSON.parse(p.name.toString()):null;t=n&&n[e]||null}return t},f=function(e,t){if(d)d.setItem(e,t);else if(p&&l.a.JSON){var n=p.name&&"{"===p.name.toString().substr(0,1)?l.a.JSON.parse(p.name.toString()):null;(n=n||{})[e]=t,p.name=l.a.JSON.stringify(n)}},m=function(){return l.a.Math.round((new l.a.Date).getTime()/1e3)},b=function(){return f("__rlT",m())},g=function(){var e=h("__rlT",0);return e&&l.a.parseInt(e,10)||0};l.a.setInterval(b,6e4)},function(e,t){var n=0,o=Math.random();e.exports=function(e){return"Symbol(".concat(void 0===e?"":e,")_",(++n+o).toString(36))}},function(e,t){t.f={}.propertyIsEnumerable},function(e,t,n){var o=n(71),i=n(64),a=n(43),r=n(67),s=n(46),c=n(77),l=Object.getOwnPropertyDescriptor;t.f=n(42)?l:function(e,t){if(e=a(e),t=r(t,!0),c)try{return l(e,t)}catch(e){}if(s(e,t))return i(!o.f.call(e,t),e[t])}},function(e,t){e.exports=function(e){if(void 0==e)throw TypeError("Can't call method on "+e);return e}},function(e,t,n){"use strict";n.d(t,"a",function(){return d});var o=n(8),i=n.n(o),a=n(12),r=n.n(a),s=n(11),c=n.n(s),l=n(1),u=n(2),d=function(e){function t(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};i()(this,t);var o=r()(this,e.call(this));return o.value=n.value,!Object(u.isUnd)(o.value)&&o.value.subscribe||(o.value=l.a.observable(!Object(u.isUnd)(o.value)&&!!o.value)),o.enable=n.enable,!Object(u.isUnd)(o.enable)&&o.enable.subscribe||(o.enable=l.a.observable(!!Object(u.isUnd)(o.enable)||!!o.enable)),o.disable=n.disable,!Object(u.isUnd)(o.disable)&&o.disable.subscribe||(o.disable=l.a.observable(!Object(u.isUnd)(o.disable)&&!!o.disable)),o.label=n.label||"",o.inline=!Object(u.isUnd)(n.inline)&&n.inline,o.readOnly=!Object(u.isUnd)(n.readOnly)&&!!n.readOnly,o.inverted=!Object(u.isUnd)(n.inverted)&&!!n.inverted,o.labeled=!Object(u.isUnd)(n.label),o.labelAnimated=!!n.labelAnimated,o}return c()(t,e),t.prototype.click=function(){this.readOnly||!this.enable()||this.disable()||this.value(!this.value())},t}(n(27).a)},function(e,t){e.exports=window.crossroads},function(e,t,n){"use strict";function o(e){var t=[],n=[],i=[];return new r(e).tokenize().forEach(function(e){"operator"!==e.type||","!==e.value&&";"!==e.value?n.push(e):(n.length&&t.push(n),n=[])}),n.length&&t.push(n),t.forEach(function(e){(e=function(e){for(var t=!1,n="text",i=void 0,a=[],r={address:[],comment:[],group:[],text:[]},s=0,c=e.length;s=0;u--)if(r.text[u].match(/^[^@\s]+@[^@\s]+$/)){r.address=r.text.splice(u,1);break}if(!r.address.length)for(var d=r.text.length-1;d>=0&&(r.text[d]=r.text[d].replace(/\s*\b[^@\s]+@[^@\s]+\b\s*/,function(e){return r.address.length?e:(r.address=[e.trim()]," ")}).trim(),!r.address.length);d--);}if(!r.text.length&&r.comment.length&&(r.text=r.comment,r.comment=[]),r.address.length>1&&(r.text=r.text.concat(r.address.splice(1))),r.text=r.text.join(" "),r.address=r.address.join(" "),!r.address&&t)return[];(i={address:r.address||r.text||"",name:r.text||r.address||""}).address===i.name&&((i.address||"").match(/@/)?i.name="":i.address=""),a.push(i)}return a}(e)).length&&(i=i.concat(e))}),i}Object.defineProperty(t,"__esModule",{value:!0});var i=function(){function e(e,t){for(var n=0;n",",":"",":":";",";":""},r=function(){function e(t){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.str=(t||"").toString(),this.operatorCurrent="",this.operatorExpecting="",this.node=null,this.escaped=!1,this.list=[]}return i(e,[{key:"tokenize",value:function(){for(var e=void 0,t=[],n=0,o=this.str.length;n+$/,""),this.fileNameExt=Object(b.getFileExtension)(this.fileName),this.fileType=S(this.fileNameExt,this.mimeType),t=!0),t},t.prototype.isImage=function(){return f.FileType.Image===this.fileType},t.prototype.isMp3=function(){return f.FileType.Audio===this.fileType&&"mp3"===this.fileNameExt},t.prototype.isOgg=function(){return f.FileType.Audio===this.fileType&&("oga"===this.fileNameExt||"ogg"===this.fileNameExt)},t.prototype.isWav=function(){return f.FileType.Audio===this.fileType&&"wav"===this.fileNameExt},t.prototype.hasThumbnail=function(){return this.isThumbnail},t.prototype.isText=function(){return f.FileType.Text===this.fileType||f.FileType.Eml===this.fileType||f.FileType.Certificate===this.fileType||f.FileType.Html===this.fileType||f.FileType.Code===this.fileType},t.prototype.isPdf=function(){return f.FileType.Pdf===this.fileType},t.prototype.isFramed=function(){return this.framed&&m.data.__APP__&&m.data.__APP__.googlePreviewSupported()&&!(this.isPdf()&&m.bAllowPdfPreview)&&!this.isText()&&!this.isImage()},t.prototype.hasPreview=function(){return this.isImage()||this.isPdf()&&m.bAllowPdfPreview||this.isText()||this.isFramed()},t.prototype.hasPreplay=function(){return v.a.supportedMp3&&this.isMp3()||v.a.supportedOgg&&this.isOgg()||v.a.supportedWav&&this.isWav()},t.prototype.linkDownload=function(){return Object(g.c)(this.download)},t.prototype.linkPreview=function(){return Object(g.e)(this.download)},t.prototype.linkThumbnail=function(){return this.hasThumbnail()?Object(g.g)(this.download):""},t.prototype.linkThumbnailPreviewStyle=function(){var e=this.linkThumbnail();return""===e?"":"background:url("+e+")"},t.prototype.linkFramed=function(){return Object(g.d)(this.download)},t.prototype.linkPreviewAsPlain=function(){return Object(g.f)(this.download)},t.prototype.linkPreviewMain=function(){var e="";switch(!0){case this.isImage():case this.isPdf()&&m.bAllowPdfPreview:e=this.linkPreview();break;case this.isText():e=this.linkPreviewAsPlain();break;case this.isFramed():e=this.linkFramed()}return e},t.prototype.generateTransferDownloadUrl=function(){var e=this.linkDownload();return"http"!==e.substr(0,4)&&(e=u.a.location.protocol+"//"+u.a.location.host+u.a.location.pathname+e),this.mimeType+":"+this.fileName+":"+e},t.prototype.eventDragStart=function(e,t){var n=t.originalEvent||t;return e&&n&&n.dataTransfer&&n.dataTransfer.setData&&n.dataTransfer.setData("DownloadURL",this.generateTransferDownloadUrl()),!0},t.prototype.iconClass=function(){return O(this.fileType)[0]},t.prototype.iconText=function(){return O(this.fileType)[1]},t}(y.a)},function(e,t,n){"use strict";n.r(t);var o=n(8),i=n.n(o),a=n(12),r=n.n(a),s=n(11),c=n.n(s),l=n(27),u=function(e){function t(){return i()(this,t),r()(this,e.apply(this,arguments))}return c()(t,e),t}(n(74).a);t.default=Object(l.b)(u,"CheckboxComponent")},function(e,t,n){var o=n(41),i=n(40),a=n(90),r=n(82),s=n(49).f;e.exports=function(e){var t=i.Symbol||(i.Symbol=a?{}:o.Symbol||{});"_"==e.charAt(0)||e in t||s(t,e,{value:r.f(e)})}},function(e,t,n){t.f=n(60)},function(e,t,n){var o=n(49).f,i=n(46),a=n(60)("toStringTag");e.exports=function(e,t,n){e&&!i(e=n?e:e.prototype,a)&&o(e,a,{configurable:!0,value:t})}},function(e,t){e.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},function(e,t,n){var o=n(41),i=o["__core-js_shared__"]||(o["__core-js_shared__"]={});e.exports=function(e){return i[e]||(i[e]={})}},function(e,t,n){var o=n(85)("keys"),i=n(70);e.exports=function(e){return o[e]||(o[e]=i(e))}},function(e,t,n){var o=n(104),i=n(84);e.exports=Object.keys||function(e){return o(e,i)}},function(e,t,n){var o=n(61),i=n(164),a=n(84),r=n(86)("IE_PROTO"),s=function(){},c=function(){var e,t=n(93)("iframe"),o=a.length;for(t.style.display="none",n(160).appendChild(t),t.src="javascript:",(e=t.contentWindow.document).open(),e.write("', '<\/script>', - \str_replace($aJsonReplaces[0], $aJsonReplaces[1], $sText)); - } - - /** - * @param array $aInput - */ - public static function ClearArrayUtf8Values(&$aInput) - { - if (\is_array($aInput)) - { - foreach ($aInput as $mKey => $mItem) - { - if (\is_string($mItem)) - { - $aInput[$mKey] = \MailSo\Base\Utils::Utf8Clear($mItem); - } - else if (\is_array($mItem)) - { - \MailSo\Base\Utils::ClearArrayUtf8Values($mItem); - $aInput[$mKey] = $mItem; - } - } - } - } - - /** - * @param mixed $mInput - * @param \MailSo\Log\Logger|null $oLogger = null - * - * @return string - */ - public static function Php2js($mInput, $oLogger = null) - { - static $iOpt = null; - if (null === $iOpt) - { - $iOpt = \defined('JSON_UNESCAPED_UNICODE') ? JSON_UNESCAPED_UNICODE : 0; - } - - $sResult = @\json_encode($mInput, $iOpt); - if (!\is_string($sResult) || '' === $sResult) - { - if (!$oLogger && \MailSo\Log\Logger::IsSystemEnabled()) - { - $oLogger = \MailSo\Config::$SystemLogger; - } - - if (!($oLogger instanceof \MailSo\Log\Logger)) - { - $oLogger = null; - } - - if ($oLogger) - { - $oLogger->Write('json_encode: '.\trim( - (\MailSo\Base\Utils::FunctionExistsAndEnabled('json_last_error') ? ' [Error Code: '.\json_last_error().']' : ''). - (\MailSo\Base\Utils::FunctionExistsAndEnabled('json_last_error_msg') ? ' [Error Message: '.\json_last_error_msg().']' : '') - ), \MailSo\Log\Enumerations\Type::WARNING, 'JSON' - ); - } - - if (\is_array($mInput)) - { - if ($oLogger) - { - $oLogger->WriteDump($mInput, \MailSo\Log\Enumerations\Type::INFO, 'JSON'); - $oLogger->Write('Trying to clear Utf8 before json_encode', \MailSo\Log\Enumerations\Type::INFO, 'JSON'); - } - - \MailSo\Base\Utils::ClearArrayUtf8Values($mInput); - $sResult = @\json_encode($mInput, $iOpt); - } - } - - return $sResult; - } - - /** - * @param string $sFileName - * - * @return string - */ - public static function ClearFileName($sFileName) - { - return \MailSo\Base\Utils::Trim(\MailSo\Base\Utils::ClearNullBite( - \MailSo\Base\Utils::StripSpaces( - \str_replace(array('"', '/', '\\', '*', '?', '<', '>', '|', ':'), ' ', $sFileName)))); - } - - /** - * @param string $sValue - * - * @return string - */ - public static function ClearXss($sValue) - { - return \MailSo\Base\Utils::Trim(\MailSo\Base\Utils::ClearNullBite( - \str_replace(array('"', '/', '\\', '*', '?', '<', '>', '|', ':'), ' ', $sValue))); - } - - /** - * @param string $sValue - * - * @return string - */ - public static function Trim($sValue) - { - return \trim(\preg_replace('/^[\x00-\x1F]+/u', '', - \preg_replace('/[\x00-\x1F]+$/u', '', \trim($sValue)))); - } - - /** - * @param string $sDir - * - * @return bool - */ - public static function RecRmDir($sDir) - { - if (@\is_dir($sDir)) - { - $aObjects = \scandir($sDir); - foreach ($aObjects as $sObject) - { - if ('.' !== $sObject && '..' !== $sObject) - { -// if ('dir' === \filetype($sDir.'/'.$sObject)) - if (\is_dir($sDir.'/'.$sObject)) - { - self::RecRmDir($sDir.'/'.$sObject); - } - else - { - @\unlink($sDir.'/'.$sObject); - } - } - } - - return @\rmdir($sDir); - } - - return false; - } - - /** - * @param string $sSource - * @param string $sDestination - */ - public static function CopyDir($sSource, $sDestination) - { - if (\is_dir($sSource)) - { - if (!\is_dir($sDestination)) - { - \mkdir($sDestination); - } - - $oDirectory = \dir($sSource); - if ($oDirectory) - { - while (false !== ($sRead = $oDirectory->read())) - { - if ('.' === $sRead || '..' === $sRead) - { - continue; - } - - $sPathDir = $sSource.'/'.$sRead; - if (\is_dir($sPathDir)) - { - \MailSo\Base\Utils::CopyDir($sPathDir, $sDestination.'/'.$sRead); - continue; - } - - \copy($sPathDir, $sDestination.'/'.$sRead); - } - - $oDirectory->close(); - } - } - } - - /** - * @param string $sTempPath - * @param int $iTime2Kill - * @param int $iNow - * - * @return bool - */ - public static function RecTimeDirRemove($sTempPath, $iTime2Kill, $iNow) - { - $iFileCount = 0; - - $sTempPath = rtrim($sTempPath, '\\/'); - if (@\is_dir($sTempPath)) - { - $rDirH = @\opendir($sTempPath); - if ($rDirH) - { - $bRemoveAllDirs = true; - while (($sFile = @\readdir($rDirH)) !== false) - { - if ('.' !== $sFile && '..' !== $sFile) - { - if (@\is_dir($sTempPath.'/'.$sFile)) - { - if (!\MailSo\Base\Utils::RecTimeDirRemove($sTempPath.'/'.$sFile, $iTime2Kill, $iNow)) - { - $bRemoveAllDirs = false; - } - } - else - { - $iFileCount++; - } - } - } - - @\closedir($rDirH); - } - - if ($iFileCount > 0) - { - if (\MailSo\Base\Utils::TimeFilesRemove($sTempPath, $iTime2Kill, $iNow)) - { - return @\rmdir($sTempPath); - } - } - else - { - return $bRemoveAllDirs ? @\rmdir($sTempPath) : false; - } - - return false; - } - - return true; - } - - /** - * @param string $sTempPath - * @param int $iTime2Kill - * @param int $iNow - */ - public static function TimeFilesRemove($sTempPath, $iTime2Kill, $iNow) - { - $bResult = true; - - $sTempPath = rtrim($sTempPath, '\\/'); - if (@\is_dir($sTempPath)) - { - $rDirH = @\opendir($sTempPath); - if ($rDirH) - { - while (($sFile = @\readdir($rDirH)) !== false) - { - if ($sFile !== '.' && $sFile !== '..') - { - if ($iNow - \filemtime($sTempPath.'/'.$sFile) > $iTime2Kill) - { - @\unlink($sTempPath.'/'.$sFile); - } - else - { - $bResult = false; - } - } - } - - @\closedir($rDirH); - } - } - - return $bResult; - } - - /** - * @param string $sUtfString - * @param int $iLength - * - * @return string - */ - public static function Utf8Truncate($sUtfString, $iLength) - { - if (\strlen($sUtfString) <= $iLength) - { - return $sUtfString; - } - - while ($iLength >= 0) - { - if ((\ord($sUtfString[$iLength]) < 0x80) || (\ord($sUtfString[$iLength]) >= 0xC0)) - { - return \substr($sUtfString, 0, $iLength); - } - - $iLength--; - } - - return ''; - } - - /** - * @param string $sUtfString - * @param string $sReplaceOn = '' - * - * @return string - */ - public static function Utf8Clear($sUtfString, $sReplaceOn = '') - { - if ('' === $sUtfString) - { - return $sUtfString; - } - - $sUtfString = \preg_replace(\MailSo\Base\Utils::$sValidUtf8Regexp, '$1', $sUtfString); - - $sUtfString = \preg_replace( - '/\xE0[\x80-\x9F][\x80-\xBF]'. - '|\xEF\xBF\xBF'. - '|\xED[\xA0-\xBF][\x80-\xBF]/S', $sReplaceOn, $sUtfString); - - $sUtfString = \preg_replace('/\xEF\xBF\xBD/', '?', $sUtfString); - - $sNewUtfString = false; - if (false === $sNewUtfString && \MailSo\Base\Utils::IsMbStringSupported()) - { - $sNewUtfString = \MailSo\Base\Utils::MbConvertEncoding($sUtfString, 'UTF-8', 'UTF-8'); - } - - if (false === $sNewUtfString && \MailSo\Base\Utils::IsIconvSupported()) - { - $sNewUtfString = \MailSo\Base\Utils::IconvConvertEncoding($sUtfString, 'UTF-8', 'UTF-8'); - } - - if (false !== $sNewUtfString) - { - $sUtfString = $sNewUtfString; - } - - return $sUtfString; - } - - /** - * @param string $sUtfString - * - * @return bool - */ - public static function IsRTL($sUtfString) - { - // \x{0591}-\x{05F4} - Hebrew - // \x{0600}-\x{068F} - Arabic - // \x{0750}-\x{077F} - Arabic - // \x{08A0}-\x{08FF} - Arabic - // \x{103A0}-\x{103DF} - Old Persian - return 0 < (int) preg_match('/[\x{0591}-\x{05F4}\x{0600}-\x{068F}\x{0750}-\x{077F}\x{08A0}-\x{08FF}\x{103A0}-\x{103DF}]/u', $sUtfString); - } - - /** - * @param string $sString - * - * @return string - */ - public static function Base64Decode($sString) - { - $sResultString = \base64_decode($sString, true); - if (false === $sResultString) - { - $sString = \str_replace(array(' ', "\r", "\n", "\t"), '', $sString); - $sString = \preg_replace('/[^a-zA-Z0-9=+\/](.*)$/', '', $sString); - - if (false !== \strpos(\trim(\trim($sString), '='), '=')) - { - $sString = \preg_replace('/=([^=])/', '= $1', $sString); - $aStrings = \explode(' ', $sString); - foreach ($aStrings as $iIndex => $sParts) - { - $aStrings[$iIndex] = \base64_decode($sParts); - } - - $sResultString = \implode('', $aStrings); - } - else - { - $sResultString = \base64_decode($sString); - } - } - - return $sResultString; - } - - /** - * @param string $sValue - * - * @return string - */ - public static function UrlSafeBase64Encode($sValue) - { - return \rtrim(\strtr(\base64_encode($sValue), '+/', '-_'), '='); - } - - /** - * @param string $sValue - * - * @return string - */ - public static function UrlSafeBase64Decode($sValue) - { - $sValue = \rtrim(\strtr($sValue, '-_.', '+/='), '='); - return \MailSo\Base\Utils::Base64Decode(\str_pad($sValue, \strlen($sValue) + (\strlen($sValue) % 4), '=', STR_PAD_RIGHT)); - } - - /** - * @param string $sSequence - * - * @return array - */ - public static function ParseFetchSequence($sSequence) - { - $aResult = array(); - $sSequence = \trim($sSequence); - if (0 < \strlen($sSequence)) - { - $aSequence = \explode(',', $sSequence); - foreach ($aSequence as $sItem) - { - if (false === \strpos($sItem, ':')) - { - $aResult[] = (int) $sItem; - } - else - { - $aItems = \explode(':', $sItem); - $iMax = \max($aItems[0], $aItems[1]); - - for ($iIndex = $aItems[0]; $iIndex <= $iMax; $iIndex++) - { - $aResult[] = (int) $iIndex; - } - } - } - } - - return $aResult; - } - /** - * @param array $aSequence - * - * @return string - */ - public static function PrepearFetchSequence($aSequence) - { - $aResult = array(); - if (\is_array($aSequence) && 0 < \count($aSequence)) - { - $iStart = null; - $iPrev = null; - - foreach ($aSequence as $sItem) - { - // simple protection - if (false !== \strpos($sItem, ':')) - { - $aResult[] = $sItem; - continue; - } - - $iItem = (int) $sItem; - if (null === $iStart || null === $iPrev) - { - $iStart = $iItem; - $iPrev = $iItem; - continue; - } - - if ($iPrev === $iItem - 1) - { - $iPrev = $iItem; - } - else - { - $aResult[] = $iStart === $iPrev ? $iStart : $iStart.':'.$iPrev; - $iStart = $iItem; - $iPrev = $iItem; - } - } - - if (null !== $iStart && null !== $iPrev) - { - $aResult[] = $iStart === $iPrev ? $iStart : $iStart.':'.$iPrev; - } - } - - return \implode(',', $aResult); - } - - /** - * - * @param resource $fResource - * @param int $iBufferLen = 8192 - * - * @return bool - */ - public static function FpassthruWithTimeLimitReset($fResource, $iBufferLen = 8192) - { - $bResult = false; - if (\is_resource($fResource)) - { - while (!\feof($fResource)) - { - $sBuffer = @\fread($fResource, $iBufferLen); - if (false !== $sBuffer) - { - echo $sBuffer; - \MailSo\Base\Utils::ResetTimeLimit(); - continue; - } - - break; - } - - $bResult = true; - } - - return $bResult; - } - - /** - * @param resource $rRead - * @param array $aWrite - * @param int $iBufferLen = 8192 - * @param bool $bResetTimeLimit = true - * @param bool $bFixCrLf = false - * @param bool $bRewindOnComplete = false - * - * @return int|bool - */ - public static function MultipleStreamWriter($rRead, $aWrite, $iBufferLen = 8192, $bResetTimeLimit = true, $bFixCrLf = false, $bRewindOnComplete = false) - { - $mResult = false; - if ($rRead && \is_array($aWrite) && 0 < \count($aWrite)) - { - $mResult = 0; - while (!\feof($rRead)) - { - $sBuffer = \fread($rRead, $iBufferLen); - if (false === $sBuffer) - { - $mResult = false; - break; - } - - if (0 === $iBufferLen || '' === $sBuffer) - { - break; - } - - if ($bFixCrLf) - { - $sBuffer = \str_replace("\n", "\r\n", \str_replace("\r", '', $sBuffer)); - } - - $mResult += \strlen($sBuffer); - - foreach ($aWrite as $rWriteStream) - { - $mWriteResult = \fwrite($rWriteStream, $sBuffer); - if (false === $mWriteResult) - { - $mResult = false; - break 2; - } - } - - if ($bResetTimeLimit) - { - \MailSo\Base\Utils::ResetTimeLimit(); - } - } - } - - if ($mResult && $bRewindOnComplete) - { - foreach ($aWrite as $rWriteStream) - { - if (\is_resource($rWriteStream)) - { - @\rewind($rWriteStream); - } - } - } - - return $mResult; - } - - /** - * @param string $sUtfModifiedString - * - * @return string - */ - public static function ModifiedToPlainUtf7($sUtfModifiedString) - { - $sUtf = ''; - $bBase = false; - - for ($iIndex = 0, $iLen = \strlen($sUtfModifiedString); $iIndex < $iLen; $iIndex++) - { - if ('&' === $sUtfModifiedString[$iIndex]) - { - if (isset($sUtfModifiedString[$iIndex+1]) && '-' === $sUtfModifiedString[$iIndex + 1]) - { - $sUtf .= '&'; - $iIndex++; - } - else - { - $sUtf .= '+'; - $bBase = true; - } - } - else if ($sUtfModifiedString[$iIndex] == '-' && $bBase) - { - $bBase = false; - } - else - { - if ($bBase && ',' === $sUtfModifiedString[$iIndex]) - { - $sUtf .= '/'; - } - else if (!$bBase && '+' === $sUtfModifiedString[$iIndex]) - { - $sUtf .= '+-'; - } - else - { - $sUtf .= $sUtfModifiedString[$iIndex]; - } - } - } - - return $sUtf; - } - - /** - * @param string $sStr - * - * @return string|bool - */ - public static function Utf7ModifiedToUtf8($sStr) - { - $aArray = array(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,62, 63,-1,-1,-1,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,-1,0,1,2,3,4,5,6,7,8,9, - 10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, - 41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1); - - $sResult = ''; - $bError = false; - $iLen = \strlen($sStr); - - for ($iIndex = 0; $iLen > 0; $iIndex++, $iLen--) - { - $sChar = $sStr{$iIndex}; - if ($sChar == '&') - { - $iIndex++; - $iLen--; - - $sChar = isset($sStr{$iIndex}) ? $sStr{$iIndex} : null; - if ($sChar === null) - { - break; - } - - if ($iLen && $sChar == '-') - { - $sResult .= '&'; - continue; - } - - $iCh = 0; - $iK = 10; - for (; $iLen > 0; $iIndex++, $iLen--) - { - $sChar = $sStr{$iIndex}; - - $iB = $aArray[\ord($sChar)]; - if ((\ord($sChar) & 0x80) || $iB == -1) - { - break; - } - - if ($iK > 0) - { - $iCh |= $iB << $iK; - $iK -= 6; - } - else - { - $iCh |= $iB >> (-$iK); - if ($iCh < 0x80) - { - if (0x20 <= $iCh && $iCh < 0x7f) - { - return $bError; - } - - $sResult .= \chr($iCh); - } - else if ($iCh < 0x800) - { - $sResult .= \chr(0xc0 | ($iCh >> 6)); - $sResult .= \chr(0x80 | ($iCh & 0x3f)); - } - else - { - $sResult .= \chr(0xe0 | ($iCh >> 12)); - $sResult .= \chr(0x80 | (($iCh >> 6) & 0x3f)); - $sResult .= \chr(0x80 | ($iCh & 0x3f)); - } - - $iCh = ($iB << (16 + $iK)) & 0xffff; - $iK += 10; - } - } - - if (($iCh || $iK < 6) || - (!$iLen || $sChar != '-') || - ($iLen > 2 && '&' === $sStr{$iIndex+1} && '-' !== $sStr{$iIndex+2})) - { - return $bError; - } - } - else if (\ord($sChar) < 0x20 || \ord($sChar) >= 0x7f) - { - return $bError; - } - else - { - $sResult .= $sChar; - } - } - - return $sResult; - } - - /** - * @param string $sStr - * - * @return string|bool - */ - public static function Utf8ToUtf7Modified($sStr) - { - $sArray = array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S', - 'T','U','V','W','X','Y','Z', 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o', - 'p','q','r','s','t','u','v','w','x','y','z', '0','1','2','3','4','5','6','7','8','9','+',','); - - $sLen = \strlen($sStr); - $bIsB = false; - $iIndex = $iN = 0; - $sReturn = ''; - $bError = false; - $iCh = $iB = $iK = 0; - - while ($sLen) - { - $iC = \ord($sStr{$iIndex}); - if ($iC < 0x80) - { - $iCh = $iC; - $iN = 0; - } - else if ($iC < 0xc2) - { - return $bError; - } - else if ($iC < 0xe0) - { - $iCh = $iC & 0x1f; - $iN = 1; - } - else if ($iC < 0xf0) - { - $iCh = $iC & 0x0f; - $iN = 2; - } - else if ($iC < 0xf8) - { - $iCh = $iC & 0x07; - $iN = 3; - } - else if ($iC < 0xfc) - { - $iCh = $iC & 0x03; - $iN = 4; - } - else if ($iC < 0xfe) - { - $iCh = $iC & 0x01; - $iN = 5; - } - else - { - return $bError; - } - - $iIndex++; - $sLen--; - - if ($iN > $sLen) - { - return $bError; - } - - for ($iJ = 0; $iJ < $iN; $iJ++) - { - $iO = \ord($sStr{$iIndex+$iJ}); - if (($iO & 0xc0) != 0x80) - { - return $bError; - } - - $iCh = ($iCh << 6) | ($iO & 0x3f); - } - - if ($iN > 1 && !($iCh >> ($iN * 5 + 1))) - { - return $bError; - } - - $iIndex += $iN; - $sLen -= $iN; - - if ($iCh < 0x20 || $iCh >= 0x7f) - { - if (!$bIsB) - { - $sReturn .= '&'; - $bIsB = true; - $iB = 0; - $iK = 10; - } - - if ($iCh & ~0xffff) - { - $iCh = 0xfffe; - } - - $sReturn .= $sArray[($iB | $iCh >> $iK)]; - $iK -= 6; - for (; $iK >= 0; $iK -= 6) - { - $sReturn .= $sArray[(($iCh >> $iK) & 0x3f)]; - } - - $iB = ($iCh << (-$iK)) & 0x3f; - $iK += 16; - } - else - { - if ($bIsB) - { - if ($iK > 10) - { - $sReturn .= $sArray[$iB]; - } - $sReturn .= '-'; - $bIsB = false; - } - - $sReturn .= \chr($iCh); - if ('&' === \chr($iCh)) - { - $sReturn .= '-'; - } - } - } - - if ($bIsB) - { - if ($iK > 10) - { - $sReturn .= $sArray[$iB]; - } - - $sReturn .= '-'; - } - - return $sReturn; - } - - /** - * @param string|array $mFunctionNameOrNames - * - * @return bool - */ - public static function FunctionExistsAndEnabled($mFunctionNameOrNames) - { - static $aCache = null; - - if (\is_array($mFunctionNameOrNames)) - { - foreach ($mFunctionNameOrNames as $sFunctionName) - { - if (!\MailSo\Base\Utils::FunctionExistsAndEnabled($sFunctionName)) - { - return false; - } - } - - return true; - } - - if (empty($mFunctionNameOrNames) || !\function_exists($mFunctionNameOrNames) || !\is_callable($mFunctionNameOrNames)) - { - return false; - } - - if (null === $aCache) - { - $sDisableFunctions = @\ini_get('disable_functions'); - $sDisableFunctions = \is_string($sDisableFunctions) && 0 < \strlen($sDisableFunctions) ? $sDisableFunctions : ''; - - $aCache = \explode(',', $sDisableFunctions); - $aCache = \is_array($aCache) && 0 < \count($aCache) ? $aCache : array(); - - if (\extension_loaded('suhosin')) - { - $sSuhosin = @\ini_get('suhosin.executor.func.blacklist'); - $sSuhosin = \is_string($sSuhosin) && 0 < \strlen($sSuhosin) ? $sSuhosin : ''; - - $aSuhosinCache = \explode(',', $sSuhosin); - $aSuhosinCache = \is_array($aSuhosinCache) && 0 < \count($aSuhosinCache) ? $aSuhosinCache : array(); - - if (0 < \count($aSuhosinCache)) - { - $aCache = \array_merge($aCache, $aSuhosinCache); - $aCache = \array_unique($aCache); - } - } - } - - return !\in_array($mFunctionNameOrNames, $aCache); - } - - /** - * @param string $mValue - * - * @return string - */ - public static function ClearNullBite($mValue) - { - return \str_replace('%00', '', $mValue); - } - - /** - * @param mixed $mValue - * @param bool $bClearNullBite = false - * - * @return mixed - */ - public static function StripSlashesValue($mValue, $bClearNullBite = false) - { - static $bIsMagicQuotesOn = null; - if (null === $bIsMagicQuotesOn) - { - $bIsMagicQuotesOn = (bool) @\ini_get('magic_quotes_gpc'); - } - - if (!$bIsMagicQuotesOn) - { - return $bClearNullBite && \is_string($mValue) ? \MailSo\Base\Utils::ClearNullBite($mValue) : $mValue; - } - - $sType = \gettype($mValue); - if ('string' === $sType) - { - return \stripslashes($bClearNullBite ? \MailSo\Base\Utils::ClearNullBite($mValue) : $mValue); - } - else if ('array' === $sType) - { - $aReturnValue = array(); - $mValueKeys = \array_keys($mValue); - foreach ($mValueKeys as $sKey) - { - $aReturnValue[$sKey] = \MailSo\Base\Utils::StripSlashesValue($mValue[$sKey], $bClearNullBite); - } - - return $aReturnValue; - } - - return $mValue; - } - - /** - * @param string $sStr - * - * @return string - */ - public static function CharsetDetect($sStr) - { - $mResult = ''; - if (!\MailSo\Base\Utils::IsAscii($sStr)) - { - $mResult = \MailSo\Base\Utils::IsMbStringSupported() && - \MailSo\Base\Utils::FunctionExistsAndEnabled('mb_detect_encoding') ? - @\mb_detect_encoding($sStr, 'auto', true) : false; - - if (false === $mResult && \MailSo\Base\Utils::IsIconvSupported()) - { - $mResult = \md5(@\iconv('utf-8', 'utf-8//IGNORE', $sStr)) === \md5($sStr) ? 'utf-8' : ''; - } - } - - return \is_string($mResult) && 0 < \strlen($mResult) ? $mResult : ''; - } - - /** - * @param string $sAdditionalSalt = '' - * - * @return string - */ - public static function Md5Rand($sAdditionalSalt = '') - { - return \md5(\microtime(true).\rand(10000, 99999). - \md5($sAdditionalSalt).\rand(10000, 99999).\microtime(true)); - } - - /** - * @param string $sAdditionalSalt = '' - * - * @return string - */ - public static function Sha1Rand($sAdditionalSalt = '') - { - return \sha1(\microtime(true).\rand(10000, 99999). - \sha1($sAdditionalSalt).\rand(10000, 99999).\microtime(true)); - } - - /** - * @param string $sData - * @param string $sKey - * - * @return string - */ - public static function Hmac($sData, $sKey) - { - if (\function_exists('hash_hmac')) - { - return \hash_hmac('md5', $sData, $sKey); - } - - $iLen = 64; - if ($iLen < \strlen($sKey)) - { - $sKey = \pack('H*', \md5($sKey)); - } - - $sKey = \str_pad($sKey, $iLen, \chr(0x00)); - $sIpad = \str_pad('', $iLen, \chr(0x36)); - $sOpad = \str_pad('', $iLen, \chr(0x5c)); - - return \md5(($sKey ^ $sOpad).\pack('H*', \md5(($sKey ^ $sIpad).$sData))); - } - - /** - * @param string $sDomain - * @param bool $bSimple = false - * - * @return bool - */ - public static function ValidateDomain($sDomain, $bSimple = false) - { - $aMatch = array(); - if ($bSimple) - { - return \preg_match('/.+(\.[a-zA-Z]+)$/', $sDomain, $aMatch) && !empty($aMatch[1]); - } - - return \preg_match('/.+(\.[a-zA-Z]+)$/', $sDomain, $aMatch) && !empty($aMatch[1]) && \in_array($aMatch[1], \explode(' ', - '.academy .actor .agency .audio .bar .beer .bike .blue .boutique .cab .camera .camp .capital .cards .careers .cash .catering .center .cheap .city .cleaning .clinic .clothing .club .coffee .community .company .computer .construction .consulting .contractors .cool .credit .dance .dating .democrat .dental .diamonds .digital .direct .directory .discount .domains .education .email .energy .equipment .estate .events .expert .exposed .fail .farm .fish .fitness .florist .fund .futbol .gallery .gift .glass .graphics .guru .help .holdings .holiday .host .hosting .house .institute .international .kitchen .land .life .lighting .limo .link .management .market .marketing .media .menu .moda .partners .parts .photo .photography .photos .pics .pink .press .productions .pub .red .rentals .repair .report .rest .sexy .shoes .social .solar .solutions .space .support .systems .tattoo .tax .technology .tips .today .tools .town .toys .trade .training .university .uno .vacations .vision .vodka .voyage .watch .webcam .wiki .work .works .wtf .zone .aero .asia .biz .cat .com .coop .edu .gov .info .int .jobs .mil .mobi .museum .name .net .org .pro .tel .travel .xxx .xyz '. - '.ac .ad .ae .af .ag .ai .al .am .an .ao .aq .ar .as .at .au .aw .ax .az .ba .bb .bd .be .bf .bg .bh .bi .bj .bm .bn .bo .br .bs .bt .bv .bw .by .bz .ca .cc .cd .cf .cg .ch .ci .ck .cl .cm .cn .co .cr .cs .cu .cv .cx .cy .cz .dd .de .dj .dk .dm .do .dz .ec .ee .eg .er .es .et .eu .fi .fj .fk .fm .fo .fr .ga .gb .gd .ge .gf .gg .gh .gi .gl .gm .gn .gp .gq .gr .gs .gt .gu .gw .gy .hk .hm .hn .hr .ht .hu .id .ie .il .im .in .io .iq .ir .is .it .je .jm .jo .jp .ke .kg .kh .ki .km .kn .kp .kr .kw .ky .kz .la .lb .lc .li .lk .lr .ls .lt .lu .lv .ly .ma .mc .md .me .mg .mh .mk .ml .mm .mn .mo .mp .mq .mr .ms .mt .mu .mv .mw .mx .my .mz .na .nc .ne .nf .ng .ni .nl .no .np .nr .nu .nz .om .pa .pe .pf .pg .ph .pk .pl .pm .pn .pr .ps .pt .pw .py .qa .re .ro .rs .ru . .rw .sa .sb .sc .sd .se .sg .sh .si .sj .sk .sl .sm .sn .so .sr .st .su .sv .sy .sz .tc .td .tf .tg .th .tj .tk .tl .tm .tn .to .tp .tr .tt .tv .tw .tz .ua .ug .uk .us .uy .uz .va .vc .ve .vg .vi .vn .vu .wf .ws .ye .yt .za .zm .zw' - )); - } - - /** - * @param string $sIp - * - * @return bool - */ - public static function ValidateIP($sIp) - { - return !empty($sIp) && $sIp === @\filter_var($sIp, FILTER_VALIDATE_IP); - } - - /** - * @return \Net_IDNA2 - */ - private static function idn() - { - static $oIdn = null; - if (null === $oIdn) - { - include_once MAILSO_LIBRARY_ROOT_PATH.'Vendors/Net/IDNA2.php'; - $oIdn = new \Net_IDNA2(); - $oIdn->setParams('utf8', true); - } - - return $oIdn; - } - - /** - * @param string $sStr - * @param bool $bLowerIfAscii = false - * - * @return string - */ - public static function IdnToUtf8($sStr, $bLowerIfAscii = false) - { - if (0 < \strlen($sStr) && \preg_match('/(^|\.|@)xn--/i', $sStr)) - { - try - { - $sStr = self::idn()->decode($sStr); - } - catch (\Exception $oException) {} - } - - return $bLowerIfAscii ? \MailSo\Base\Utils::StrMailDomainToLowerIfAscii($sStr) : $sStr; - } - - /** - * @param string $sStr - * @param bool $bLowerIfAscii = false - * - * @return string - */ - public static function IdnToAscii($sStr, $bLowerIfAscii = false) - { - $sStr = $bLowerIfAscii ? \MailSo\Base\Utils::StrMailDomainToLowerIfAscii($sStr) : $sStr; - - $sUser = ''; - $sDomain = $sStr; - if (false !== \strpos($sStr, '@')) - { - $sUser = \MailSo\Base\Utils::GetAccountNameFromEmail($sStr); - $sDomain = \MailSo\Base\Utils::GetDomainFromEmail($sStr); - } - - if (0 < \strlen($sDomain) && \preg_match('/[^\x20-\x7E]/', $sDomain)) - { - try - { - $sDomain = self::idn()->encode($sDomain); - } - catch (\Exception $oException) {} - } - - return ('' === $sUser ? '' : $sUser.'@').$sDomain; - } - - /** - * @param string $sHash - * @param string $sSalt - * - * @return int - */ - public static function HashToId($sHash, $sSalt = '') - { - $sData = $sHash ? @\MailSo\Base\Crypt::XxteaDecrypt(\hex2bin($sHash), \md5($sSalt)) : null; - - $aMatch = array(); - if ($sData && preg_match('/^id:(\d+)$/', $sData, $aMatch) && isset($aMatch[1])) - { - return is_numeric($aMatch[1]) ? (int) $aMatch[1] : null; - } - - return null; - } - - /** - * @param int $iID - * @param string $sSalt - * - * @return string - */ - public static function IdToHash($iID, $sSalt = '') - { - return is_int($iID) ? - \bin2hex(\MailSo\Base\Crypt::XxteaEncrypt('id:'.$iID, \md5($sSalt))) : null - ; - } - - /** - * @param string $sPassword - * - * @return bool - */ - public static function PasswordWeaknessCheck($sPassword) - { - $sPassword = \trim($sPassword); - if (6 > \strlen($sPassword)) - { - return false; - } - - $sLine = 'password 123.456 12345678 abc123 qwerty monkey letmein dragon 111.111 baseball iloveyou trustno1 1234567 sunshine master 123.123 welcome shadow ashley football jesus michael ninja mustang password1 123456 123456789 qwerty 111111 1234567 666666 12345678 7777777 123321 654321 1234567890 123123 555555 vkontakte gfhjkm 159753 777777 temppassword qazwsx 1q2w3e 1234 112233 121212 qwertyuiop qq18ww899 987654321 12345 zxcvbn zxcvbnm 999999 samsung ghbdtn 1q2w3e4r 1111111 123654 159357 131313 qazwsxedc 123qwe 222222 asdfgh 333333 9379992 asdfghjkl 4815162342 12344321 88888888 11111111 knopka 789456 qwertyu 1q2w3e4r5t iloveyou vfhbyf marina password qweasdzxc 10203 987654 yfnfif cjkysirj nikita 888888 vfrcbv k.,jdm qwertyuiop[] qwe123 qweasd natasha 123123123 fylhtq q1w2e3 stalker 1111111111 q1w2e3r4 nastya 147258369 147258 fyfcnfcbz 1234554321 1qaz2wsx andrey 111222 147852 genius sergey 7654321 232323 123789 fktrcfylh spartak admin test 123 azerty abc123 lol123 easytocrack1 hello saravn holysh!t test123 tundra_cool2 456 dragon thomas killer root 1111 pass master aaaaaa a monkey daniel asdasd e10adc3949ba59abbe56e057f20f883e changeme computer jessica letmein mirage loulou lol superman shadow admin123 secret administrator sophie kikugalanetroot doudou liverpool hallo sunshine charlie parola 100827092 michael andrew password1 fuckyou matrix cjmasterinf internet hallo123 eminem demo gewinner pokemon abcd1234 guest ngockhoa martin sandra asdf hejsan george qweqwe lollipop lovers q1q1q1 tecktonik naruto 12 password12 password123 password1234 password12345 password123456 password1234567 password12345678 password123456789 000000 maximius 123abc baseball1 football1 soccer princess slipknot 11111 nokia super star 666999 12341234 1234321 135790 159951 212121 zzzzzz 121314 134679 142536 19921992 753951 7007 1111114 124578 19951995 258456 qwaszx zaqwsx 55555 77777 54321 qwert 22222 33333 99999 88888 66666'; - return false === \strpos($sLine, \strtolower($sPassword)); - } -} + 'utf-8', + '.20127' => 'iso-8859-1', + + '.1250' => 'windows-1250', + '.cp1250' => 'windows-1250', + '.cp-1250' => 'windows-1250', + '.1251' => 'windows-1251', + '.cp1251' => 'windows-1251', + '.cp-1251' => 'windows-1251', + '.1252' => 'windows-1252', + '.cp1252' => 'windows-1252', + '.cp-1252' => 'windows-1252', + '.1253' => 'windows-1253', + '.cp1253' => 'windows-1253', + '.cp-1253' => 'windows-1253', + '.1254' => 'windows-1254', + '.cp1254' => 'windows-1254', + '.cp-1254' => 'windows-1254', + '.1255' => 'windows-1255', + '.cp1255' => 'windows-1255', + '.cp-1255' => 'windows-1255', + '.1256' => 'windows-1256', + '.cp1256' => 'windows-1256', + '.cp-1256' => 'windows-1256', + '.1257' => 'windows-1257', + '.cp1257' => 'windows-1257', + '.cp-1257' => 'windows-1257', + '.1258' => 'windows-1258', + '.cp1258' => 'windows-1258', + '.cp-1258' => 'windows-1258', + + '.28591' => 'iso-8859-1', + '.28592' => 'iso-8859-2', + '.28593' => 'iso-8859-3', + '.28594' => 'iso-8859-4', + '.28595' => 'iso-8859-5', + '.28596' => 'iso-8859-6', + '.28597' => 'iso-8859-7', + '.28598' => 'iso-8859-8', + '.28599' => 'iso-8859-9', + '.28603' => 'iso-8859-13', + '.28605' => 'iso-8859-15', + + '.1125' => 'cp1125', + '.20866' => 'koi8-r', + '.21866' => 'koi8-u', + '.950' => 'big5', + '.936' => 'euc-cn', + '.20932' => 'euc-js', + '.949' => 'euc-kr', + ); + + /** + * @access private + */ + private function __construct() + { + } + + /** + * @return string + */ + public static function DetectSystemCharset() + { + $sResult = ''; + $sLocale = @\setlocale(LC_ALL, ''); + $sLocaleLower = \strtolower(\trim($sLocale)); + + foreach (\MailSo\Base\Utils::$aLocaleMapping as $sKey => $sValue) + { + if (false !== \strpos($sLocaleLower, $sKey) || + false !== \strpos($sLocaleLower, '.'.$sValue)) + { + $sResult = $sValue; + break; + } + } + + return $sResult; + } + + /** + * @return string + */ + public static function ConvertSystemString($sSrt) + { + $sSrt = \trim($sSrt); + if (!empty($sSrt) && !\MailSo\Base\Utils::IsUtf8($sSrt)) + { + $sCharset = \MailSo\Base\Utils::DetectSystemCharset(); + if (!empty($sCharset)) + { + $sSrt = \MailSo\Base\Utils::ConvertEncoding( + $sSrt, $sCharset, \MailSo\Base\Enumerations\Charset::UTF_8); + } + else + { + $sSrt = @\utf8_encode($sSrt); + } + } + + return $sSrt; + } + + /** + * @param string $sEncoding + * @param bool $bAsciAsUtf8 = false + * + * @return string + */ + public static function NormalizeCharset($sEncoding, $bAsciAsUtf8 = false) + { + $sEncoding = \strtolower($sEncoding); + + $sEncoding = \preg_replace('/^iso8/', 'iso-8', $sEncoding); + $sEncoding = \preg_replace('/^cp-([\d])/', 'cp$1', $sEncoding); + $sEncoding = \preg_replace('/^windows?12/', 'windows-12', $sEncoding); + + switch ($sEncoding) + { + case 'asci': + case 'ascii': + case 'us-asci': + case 'us-ascii': + $sEncoding = $bAsciAsUtf8 ? \MailSo\Base\Enumerations\Charset::UTF_8 : + \MailSo\Base\Enumerations\Charset::ISO_8859_1; + break; + case 'unicode-1-1-utf-7': + case 'unicode-1-utf-7': + case 'unicode-utf-7': + $sEncoding = \MailSo\Base\Enumerations\Charset::UTF_7; + break; + case 'utf8': + case 'utf-8': + $sEncoding = \MailSo\Base\Enumerations\Charset::UTF_8; + break; + case 'utf7imap': + case 'utf-7imap': + case 'utf7-imap': + case 'utf-7-imap': + $sEncoding = \MailSo\Base\Enumerations\Charset::UTF_7_IMAP; + break; + case 'ks-c-5601-1987': + case 'ks_c_5601-1987': + case 'ks_c_5601_1987': + $sEncoding = 'euc-kr'; + break; + case 'x-gbk': + $sEncoding = 'gb2312'; + break; + case 'iso-8859-i': + case 'iso-8859-8-i': + $sEncoding = \MailSo\Base\Enumerations\Charset::ISO_8859_8; + break; + } + + return $sEncoding; + } + + /** + * @param string $sCharset + * @param string $sValue + * + * @return string + */ + public static function NormalizeCharsetByValue($sCharset, $sValue) + { + $sCharset = \MailSo\Base\Utils::NormalizeCharset($sCharset); + + if (\MailSo\Base\Enumerations\Charset::UTF_8 !== $sCharset && + \MailSo\Base\Utils::IsUtf8($sValue) && + false === \strpos($sCharset, \MailSo\Base\Enumerations\Charset::ISO_2022_JP) + ) + { + $sCharset = \MailSo\Base\Enumerations\Charset::UTF_8; + } + + return $sCharset; + } + + /** + * @param string $sFilePath + * @param function $fFileExistsCallback = null + * + * @return string + */ + public static function SmartFileExists($sFilePath, $fFileExistsCallback = null) + { + $sFilePath = \str_replace('\\', '/', \trim($sFilePath)); + if (!$fFileExistsCallback) + { + $fFileExistsCallback = function ($sPath) { + return \file_exists($sPath); + }; + } + + if (!\call_user_func($fFileExistsCallback, $sFilePath)) + { + return $sFilePath; + } + + $aFileInfo = \pathinfo($sFilePath); + + $iIndex = 0; + + do + { + $iIndex++; + + $sFilePathNew = $aFileInfo['dirname'].'/'. + \preg_replace('/\(\d{1,2}\)$/', '', $aFileInfo['filename']). + ' ('.$iIndex.')'. + (empty($aFileInfo['extension']) ? '' : '.'.$aFileInfo['extension']) + ; + + if (!\call_user_func($fFileExistsCallback, $sFilePathNew)) + { + $sFilePath = $sFilePathNew; + break; + } + else if (10 < $iIndex) + { + break; + } + } + while (true); + + return $sFilePath; + } + + /** + * @return bool + */ + public static function IsMbStringSupported() + { + return \MailSo\Config::$MBSTRING && + \MailSo\Base\Utils::FunctionExistsAndEnabled('mb_convert_encoding'); + } + + /** + * @return bool + */ + public static function IsIconvSupported() + { + return \MailSo\Config::$ICONV && + \MailSo\Base\Utils::FunctionExistsAndEnabled('iconv'); + } + + /** + * @return bool + */ + public static function IsIconvIgnoreSupported() + { + static $bCache = null; + if (null !== $bCache) + { + return $bCache; + } + + $bCache = false; + if (\MailSo\Base\Utils::IsIconvSupported()) + { + if (false !== @\iconv('', '//IGNORE', '')) + { + $bCache = true; + } + } + + return $bCache; + } + + /** + * @return bool + */ + public static function IsIconvTranslitSupported() + { + static $bCache = null; + if (null !== $bCache) + { + return $bCache; + } + + $bCache = false; + if (\MailSo\Base\Utils::IsIconvSupported()) + { + if (false !== @\iconv('', '//TRANSLIT', '')) + { + $bCache = true; + } + } + + return $bCache; + } + + /** + * @param string $sCharset + * + * @return bool + */ + public static function ValidateCharsetName($sCharset) + { + $sCharset = \strtolower(\MailSo\Base\Utils::NormalizeCharset($sCharset)); + return 0 < \strlen($sCharset) && (\in_array($sCharset, array(\MailSo\Base\Enumerations\Charset::UTF_7_IMAP)) || + \in_array($sCharset, \MailSo\Base\Utils::$SuppostedCharsets)); + } + + /** + * @param string $sInputString + * @param string $sInputFromEncoding + * @param string $sInputToEncoding + * + * @return string|bool + */ + public static function IconvConvertEncoding($sInputString, $sInputFromEncoding, $sInputToEncoding) + { + $sIconvOptions = ''; + if (\MailSo\Base\Utils::IsIconvIgnoreSupported()) + { + $sIconvOptions .= '//IGNORE'; + } +// if (\MailSo\Base\Utils::IsIconvTranslitSupported()) +// { +// $sIconvOptions .= '//TRANSLIT'; +// } + + $mResult = @\iconv(\strtoupper($sInputFromEncoding), \strtoupper($sInputToEncoding).$sIconvOptions, $sInputString); + if (false === $mResult) + { + if (\MailSo\Log\Logger::IsSystemEnabled()) + { + \MailSo\Log\Logger::SystemLog(array( + 'inc' => \strtoupper($sInputFromEncoding), + 'out' => \strtoupper($sInputToEncoding).$sIconvOptions, + 'val' => 500 < \strlen($sInputString) ? \substr($sInputString, 0, 500) : $sInputString, + 'hex' => 500 < \strlen($sInputString) ? '-- to long --' : \bin2hex($sInputString) + ), \MailSo\Log\Enumerations\Type::NOTICE); + } + + if (\MailSo\Config::$FixIconvByMbstring && \MailSo\Base\Utils::IsMbStringSupported()) + { + $mResult = \MailSo\Base\Utils::MbConvertEncoding($sInputString, $sInputFromEncoding, $sInputToEncoding); + } + } + return $mResult; + } + + /** + * @param string $sInputString + * @param string $sInputFromEncoding + * @param string $sInputToEncoding + * + * @return string|bool + */ + public static function MbConvertEncoding($sInputString, $sInputFromEncoding, $sInputToEncoding) + { + static $sMbstringSubCh = null; + if (null === $sMbstringSubCh) + { + $sMbstringSubCh = \mb_substitute_character(); + } + + \mb_substitute_character('none'); + $sResult = @\mb_convert_encoding($sInputString, \strtoupper($sInputToEncoding), \strtoupper($sInputFromEncoding)); + \mb_substitute_character($sMbstringSubCh); + + return $sResult; + } + + /** + * @param string $sInputString + * @param string $sInputFromEncoding + * @param string $sInputToEncoding + * + * @return string + */ + public static function ConvertEncoding($sInputString, $sInputFromEncoding, $sInputToEncoding) + { + $sResult = $sInputString; + + $sFromEncoding = \MailSo\Base\Utils::NormalizeCharset($sInputFromEncoding); + $sToEncoding = \MailSo\Base\Utils::NormalizeCharset($sInputToEncoding); + + if ('' === \trim($sResult) || ($sFromEncoding === $sToEncoding && \MailSo\Base\Enumerations\Charset::UTF_8 !== $sFromEncoding)) + { + return $sResult; + } + + $bUnknown = false; + switch (true) + { + default: + $bUnknown = true; + break; + + case ($sFromEncoding === \MailSo\Base\Enumerations\Charset::ISO_8859_1 && + $sToEncoding === \MailSo\Base\Enumerations\Charset::UTF_8 && + \function_exists('utf8_encode')): + + $sResult = \utf8_encode($sResult); + break; + + case ($sFromEncoding === \MailSo\Base\Enumerations\Charset::UTF_8 && + $sToEncoding === \MailSo\Base\Enumerations\Charset::ISO_8859_1 && + \function_exists('utf8_decode')): + + $sResult = \utf8_decode($sResult); + break; + + case ($sFromEncoding === \MailSo\Base\Enumerations\Charset::UTF_7_IMAP && + $sToEncoding === \MailSo\Base\Enumerations\Charset::UTF_8): + + $sResult = \MailSo\Base\Utils::Utf7ModifiedToUtf8($sResult); + if (false === $sResult) + { + $sResult = $sInputString; + } + break; + + case ($sFromEncoding === \MailSo\Base\Enumerations\Charset::UTF_8 && + $sToEncoding === \MailSo\Base\Enumerations\Charset::UTF_7_IMAP): + + $sResult = \MailSo\Base\Utils::Utf8ToUtf7Modified($sResult); + if (false === $sResult) + { + $sResult = $sInputString; + } + break; + + case ($sFromEncoding === \MailSo\Base\Enumerations\Charset::UTF_7_IMAP): + + $sResult = \MailSo\Base\Utils::ConvertEncoding( + \MailSo\Base\Utils::ModifiedToPlainUtf7($sResult), + \MailSo\Base\Enumerations\Charset::UTF_7, + $sToEncoding + ); + break; + + case (\in_array(\strtolower($sFromEncoding), \MailSo\Base\Utils::$SuppostedCharsets)): + + if (\MailSo\Base\Utils::IsIconvSupported()) + { + $sResult = \MailSo\Base\Utils::IconvConvertEncoding($sResult, $sFromEncoding, $sToEncoding); + } + else if (\MailSo\Base\Utils::IsMbStringSupported()) + { + $sResult = \MailSo\Base\Utils::MbConvertEncoding($sResult, $sFromEncoding, $sToEncoding); + } + + $sResult = (false !== $sResult) ? $sResult : $sInputString; + break; + } + + if ($bUnknown && \MailSo\Base\Utils::IsMbStringSupported()) + { + $sResult = @\mb_convert_encoding($sResult, $sToEncoding); + } + + return $sResult; + } + + /** + * @param string $sValue + * + * @return bool + */ + public static function IsAscii($sValue) + { + if ('' === \trim($sValue)) + { + return true; + } + + return !\preg_match('/[^\x09\x10\x13\x0A\x0D\x20-\x7E]/', $sValue); + } + + /** + * @param string $sValue + * + * @return string + */ + public static function StrToLowerIfAscii($sValue) + { + return \MailSo\Base\Utils::IsAscii($sValue) ? \strtolower($sValue) : $sValue; + } + + /** + * @param string $sValue + * + * @return string + */ + public static function StrToUpperIfAscii($sValue) + { + return \MailSo\Base\Utils::IsAscii($sValue) ? \strtoupper($sValue) : $sValue; + } + + /** + * @param string $sValue + * + * @return string + */ + public static function StrMailDomainToLowerIfAscii($sValue) + { + $aParts = \explode('@', $sValue, 2); + if (!empty($aParts[1])) + { + $aParts[1] = \MailSo\Base\Utils::IsAscii($aParts[1]) ? \strtolower($aParts[1]) : $aParts[1]; + } + + return \implode('@', $aParts); + } + + /** + * @param string $sValue + * + * @return string + */ + public static function StripSpaces($sValue) + { + return \MailSo\Base\Utils::Trim( + \preg_replace('/[\s]+/u', ' ', $sValue)); + } + + /** + * @param string $sValue + * + * @return bool + */ + public static function IsUtf8($sValue) + { + return (bool) (\function_exists('mb_check_encoding') ? + \mb_check_encoding($sValue, 'UTF-8') : \preg_match('//u', $sValue)); + } + + /** + * @param int $iSize + * @param int $iRound + * + * @return string + */ + public static function FormatFileSize($iSize, $iRound = 0) + { + $aSizes = array('B', 'KB', 'MB'); + for ($iIndex = 0; $iSize > 1024 && isset($aSizes[$iIndex + 1]); $iIndex++) + { + $iSize /= 1024; + } + return \round($iSize, $iRound).$aSizes[$iIndex]; + } + + /** + * @param string $sEncodedValue + * @param string $sEncodeingType + * + * @return string + */ + public static function DecodeEncodingValue($sEncodedValue, $sEncodeingType) + { + $sResult = $sEncodedValue; + switch (\strtolower($sEncodeingType)) + { + case 'q': + case 'quoted_printable': + case 'quoted-printable': + $sResult = \quoted_printable_decode($sResult); + break; + case 'b': + case 'base64': + $sResult = \MailSo\Base\Utils::Base64Decode($sResult); + break; + } + return $sResult; + } + + /** + * @param string $sInputValue + * + * @return string + */ + public static function DecodeFlowedFormat($sInputValue) + { + return \preg_replace('/ ([\r]?[\n])/m', ' ', $sInputValue); + } + + /** + * @param string $sEncodedValue + * @param string $sIncomingCharset = '' + * @param string $sForcedIncomingCharset = '' + * + * @return string + */ + public static function DecodeHeaderValue($sEncodedValue, $sIncomingCharset = '', $sForcedIncomingCharset = '') + { + $sValue = $sEncodedValue; + if (0 < \strlen($sIncomingCharset)) + { + $sIncomingCharset = \MailSo\Base\Utils::NormalizeCharsetByValue($sIncomingCharset, $sValue); + + $sValue = \MailSo\Base\Utils::ConvertEncoding($sValue, $sIncomingCharset, + \MailSo\Base\Enumerations\Charset::UTF_8); + } + + $sValue = \preg_replace('/\?=[\n\r\t\s]{1,5}=\?/m', '?==?', $sValue); + $sValue = \preg_replace('/[\r\n\t]+/m', ' ', $sValue); + + $aEncodeArray = array(''); + $aMatch = array(); +// \preg_match_all('/=\?[^\?]+\?[q|b|Q|B]\?[^\?]*?\?=/', $sValue, $aMatch); + \preg_match_all('/=\?[^\?]+\?[q|b|Q|B]\?.*?\?=/', $sValue, $aMatch); + + if (isset($aMatch[0]) && \is_array($aMatch[0])) + { + for ($iIndex = 0, $iLen = \count($aMatch[0]); $iIndex < $iLen; $iIndex++) + { + if (isset($aMatch[0][$iIndex])) + { + $iPos = @\strpos($aMatch[0][$iIndex], '*'); + if (false !== $iPos) + { + $aMatch[0][$iIndex][0] = \substr($aMatch[0][$iIndex][0], 0, $iPos); + } + } + } + + $aEncodeArray = $aMatch[0]; + } + + $aParts = array(); + + $sMainCharset = ''; + $bOneCharset = true; + + for ($iIndex = 0, $iLen = \count($aEncodeArray); $iIndex < $iLen; $iIndex++) + { + $aTempArr = array('', $aEncodeArray[$iIndex]); + if ('=?' === \substr(\trim($aTempArr[1]), 0, 2)) + { + $iPos = \strpos($aTempArr[1], '?', 2); + $aTempArr[0] = \substr($aTempArr[1], 2, $iPos - 2); + $sEncType = \strtoupper($aTempArr[1]{$iPos + 1}); + switch ($sEncType) + { + case 'Q': + $sHeaderValuePart = \str_replace('_', ' ', $aTempArr[1]); + $aTempArr[1] = \quoted_printable_decode(\substr( + $sHeaderValuePart, $iPos + 3, \strlen($sHeaderValuePart) - $iPos - 5)); + break; + case 'B': + $sHeaderValuePart = $aTempArr[1]; + $aTempArr[1] = \MailSo\Base\Utils::Base64Decode(\substr( + $sHeaderValuePart, $iPos + 3, \strlen($sHeaderValuePart) - $iPos - 5)); + break; + } + } + + if (0 < \strlen($aTempArr[0])) + { + $sCharset = 0 === \strlen($sForcedIncomingCharset) ? $aTempArr[0] : $sForcedIncomingCharset; + $sCharset = \MailSo\Base\Utils::NormalizeCharset($sCharset, true); + + if ('' === $sMainCharset) + { + $sMainCharset = $sCharset; + } + else if ($sMainCharset !== $sCharset) + { + $bOneCharset = false; + } + } + + $aParts[] = array( + $aEncodeArray[$iIndex], + $aTempArr[1], + $sCharset + ); + + unset($aTempArr); + } + + for ($iIndex = 0, $iLen = \count($aParts); $iIndex < $iLen; $iIndex++) + { + if ($bOneCharset) + { + $sValue = \str_replace($aParts[$iIndex][0], $aParts[$iIndex][1], $sValue); + } + else + { + $aParts[$iIndex][2] = \MailSo\Base\Utils::NormalizeCharsetByValue($aParts[$iIndex][2], $aParts[$iIndex][1]); + + $sValue = \str_replace($aParts[$iIndex][0], + \MailSo\Base\Utils::ConvertEncoding($aParts[$iIndex][1], $aParts[$iIndex][2], \MailSo\Base\Enumerations\Charset::UTF_8), + $sValue); + } + } + + if ($bOneCharset && 0 < \strlen($sMainCharset)) + { + $sMainCharset = \MailSo\Base\Utils::NormalizeCharsetByValue($sMainCharset, $sValue); + $sValue = \MailSo\Base\Utils::ConvertEncoding($sValue, $sMainCharset, \MailSo\Base\Enumerations\Charset::UTF_8); + } + + return $sValue; + } + + /** + * @param string $sIncHeaders + * @param string $aHeadersToRemove = array() + * + * @return string + */ + public static function RemoveHeaderFromHeaders($sIncHeaders, $aHeadersToRemove = array()) + { + $sResultHeaders = $sIncHeaders; + + if (\is_array($aHeadersToRemove) && 0 < \count($aHeadersToRemove)) + { + $aHeadersToRemove = \array_map('strtolower', $aHeadersToRemove); + + $sIncHeaders = \preg_replace('/[\r\n]+/', "\n", $sIncHeaders); + $aHeaders = \explode("\n", $sIncHeaders); + + $bSkip = false; + $aResult = array(); + + foreach ($aHeaders as $sLine) + { + if (0 < \strlen($sLine)) + { + $sFirst = \substr($sLine,0,1); + if (' ' === $sFirst || "\t" === $sFirst) + { + if (!$bSkip) + { + $aResult[] = $sLine; + } + } + else + { + $bSkip = false; + $aParts = \explode(':', $sLine, 2); + + if (!empty($aParts) && !empty($aParts[0])) + { + if (\in_array(\strtolower(\trim($aParts[0])), $aHeadersToRemove)) + { + $bSkip = true; + } + else + { + $aResult[] = $sLine; + } + } + } + } + } + + $sResultHeaders = \implode("\r\n", $aResult); + } + + return $sResultHeaders; + } + + /** + * @param string $sEncodeType + * @param string $sValue + * + * @return string + */ + public static function EncodeUnencodedValue($sEncodeType, $sValue) + { + $sValue = \trim($sValue); + if (0 < \strlen($sValue) && !\MailSo\Base\Utils::IsAscii($sValue)) + { + switch (\strtoupper($sEncodeType)) + { + case 'B': + $sValue = '=?'.\strtolower(\MailSo\Base\Enumerations\Charset::UTF_8). + '?B?'.\base64_encode($sValue).'?='; + break; + + case 'Q': + $sValue = '=?'.\strtolower(\MailSo\Base\Enumerations\Charset::UTF_8). + '?Q?'.\str_replace(array('?', ' ', '_'), array('=3F', '_', '=5F'), + \quoted_printable_encode($sValue)).'?='; + break; + } + } + + return $sValue; + } + + /** + * @unused + * + * @param string $sEncodeType + * @param string $sEncodeCharset + * @param string $sValue + * + * @return string + */ + public static function EncodeHeaderValue($sEncodeType, $sEncodeCharset, $sValue) + { + $sValue = \trim($sValue); + if (0 < \strlen($sValue) && !\MailSo\Base\Utils::IsAscii($sValue)) + { + switch (\strtoupper($sEncodeType)) + { + case 'B': + $sValue = '=?'.\strtolower($sEncodeCharset).'?B?'.\base64_encode($sValue).'?='; + break; + + case 'Q': + $sValue = '=?'.\strtolower($sEncodeCharset).'?Q?'.\str_replace( + array('?', ' ', '_'), array('=3F', '_', '=5F'), + \quoted_printable_encode($sValue)).'?='; + break; + } + } + + return \trim($sValue); + } + + /** + * @param string $sAttrName + * @param string $sValue = 'utf-8' + * @param string $sCharset = '' + * @param string $sLang = '' + * @param int $iLen = 78 + * + * @return string|bool + */ + public static function AttributeRfc2231Encode($sAttrName, $sValue, $sCharset = 'utf-8', $sLang = '', $iLen = 1000) + { + $sValue = \strtoupper($sCharset).'\''.$sLang.'\''. + \preg_replace_callback('/[\x00-\x20*\'%()<>@,;:\\\\"\/[\]?=\x80-\xFF]/', function ($match) { + return \rawurlencode($match[0]); + }, $sValue); + + $iNlen = \strlen($sAttrName); + $iVlen = \strlen($sValue); + + if (\strlen($sAttrName) + $iVlen > $iLen - 3) + { + $sections = array(); + $section = 0; + + for ($i = 0, $j = 0; $i < $iVlen; $i += $j) + { + $j = $iLen - $iNlen - \strlen($section) - 4; + $sections[$section++] = \substr($sValue, $i, $j); + } + + for ($i = 0, $n = $section; $i < $n; $i++) + { + $sections[$i] = ' '.$sAttrName.'*'.$i.'*='.$sections[$i]; + } + + return \implode(";\r\n", $sections); + } + else + { + return $sAttrName.'*='.$sValue; + } + } + /** + * @param string $sAttrName + * @param string $sValue + * + * @return string + */ + public static function EncodeHeaderUtf8AttributeValue($sAttrName, $sValue) + { + $sAttrName = \trim($sAttrName); + $sValue = \trim($sValue); + + if (0 < \strlen($sValue) && !\MailSo\Base\Utils::IsAscii($sValue)) + { + if (!empty($_SERVER['HTTP_USER_AGENT']) && 0 < \strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE')) + { + $sValue = $sAttrName.'="'.\preg_replace('/[+\s]+/', '%20', \urlencode($sValue)).'"'; + } + else + { + $sValue = \MailSo\Base\Utils::AttributeRfc2231Encode($sAttrName, $sValue); + } + } + else + { + $sValue = $sAttrName.'="'.\str_replace('"', '\\"', $sValue).'"'; + } + + return \trim($sValue); + } + + /** + * @param string $sEmail + * + * @return string + */ + public static function GetAccountNameFromEmail($sEmail) + { + $sResult = ''; + if (0 < \strlen($sEmail)) + { + $iPos = \strrpos($sEmail, '@'); + $sResult = (false === $iPos) ? $sEmail : \substr($sEmail, 0, $iPos); + } + + return $sResult; + } + + /** + * @param string $sEmail + * + * @return string + */ + public static function GetDomainFromEmail($sEmail) + { + $sResult = ''; + if (0 < \strlen($sEmail)) + { + $iPos = \strrpos($sEmail, '@'); + if (false !== $iPos && 0 < $iPos) + { + $sResult = \substr($sEmail, $iPos + 1); + } + } + + return $sResult; + } + + /** + * @param string $sDomain + * + * @return string + */ + public static function GetClearDomainName($sDomain) + { + $sResultDomain = \preg_replace( + '/^(webmail|email|mail|www|imap4|pop3|imap|pop|demo|client|ssl|secure|test|cloud|box|m)\./i', + '', $sDomain); + + return false === \strpos($sResultDomain, '.') ? $sDomain : $sResultDomain; + } + + /** + * @param string $sFileName + * + * @return string + */ + public static function GetFileExtension($sFileName) + { + $iLast = \strrpos($sFileName, '.'); + return false === $iLast ? '' : \strtolower(\substr($sFileName, $iLast + 1)); + } + + /** + * @param string $sFileName + * + * @return string + */ + public static function MimeContentType($sFileName) + { + $sResult = 'application/octet-stream'; + $sFileName = \trim(\strtolower($sFileName)); + + if ('winmail.dat' === $sFileName) + { + return 'application/ms-tnef'; + } + + $aMimeTypes = array( + + 'eml' => 'message/rfc822', + 'mime' => 'message/rfc822', + 'txt' => 'text/plain', + 'text' => 'text/plain', + 'def' => 'text/plain', + 'list' => 'text/plain', + 'in' => 'text/plain', + 'ini' => 'text/plain', + 'log' => 'text/plain', + 'sql' => 'text/plain', + 'cfg' => 'text/plain', + 'conf' => 'text/plain', + 'asc' => 'text/plain', + 'rtx' => 'text/richtext', + 'vcard' => 'text/vcard', + 'vcf' => 'text/vcard', + 'htm' => 'text/html', + 'html' => 'text/html', + 'csv' => 'text/csv', + 'ics' => 'text/calendar', + 'ifb' => 'text/calendar', + 'xml' => 'text/xml', + 'json' => 'application/json', + 'swf' => 'application/x-shockwave-flash', + 'hlp' => 'application/winhlp', + 'wgt' => 'application/widget', + 'chm' => 'application/vnd.ms-htmlhelp', + 'p10' => 'application/pkcs10', + 'p7c' => 'application/pkcs7-mime', + 'p7m' => 'application/pkcs7-mime', + 'p7s' => 'application/pkcs7-signature', + 'torrent' => 'application/x-bittorrent', + + // scripts + 'js' => 'application/javascript', + 'pl' => 'text/perl', + 'css' => 'text/css', + 'asp' => 'text/asp', + 'php' => 'application/x-httpd-php', + 'php3' => 'application/x-httpd-php', + 'php4' => 'application/x-httpd-php', + 'php5' => 'application/x-httpd-php', + 'phtml' => 'application/x-httpd-php', + + // images + 'png' => 'image/png', + 'jpg' => 'image/jpeg', + 'jpeg' => 'image/jpeg', + 'jpe' => 'image/jpeg', + 'jfif' => 'image/jpeg', + 'gif' => 'image/gif', + 'bmp' => 'image/bmp', + 'cgm' => 'image/cgm', + 'ief' => 'image/ief', + 'ico' => 'image/x-icon', + 'tif' => 'image/tiff', + 'tiff' => 'image/tiff', + 'svg' => 'image/svg+xml', + 'svgz' => 'image/svg+xml', + 'djv' => 'image/vnd.djvu', + 'djvu' => 'image/vnd.djvu', + 'webp' => 'image/webp', + + // archives + 'zip' => 'application/zip', + '7z' => 'application/x-7z-compressed', + 'rar' => 'application/x-rar-compressed', + 'exe' => 'application/x-msdownload', + 'dll' => 'application/x-msdownload', + 'scr' => 'application/x-msdownload', + 'com' => 'application/x-msdownload', + 'bat' => 'application/x-msdownload', + 'msi' => 'application/x-msdownload', + 'cab' => 'application/vnd.ms-cab-compressed', + 'gz' => 'application/x-gzip', + 'tgz' => 'application/x-gzip', + 'bz' => 'application/x-bzip', + 'bz2' => 'application/x-bzip2', + 'deb' => 'application/x-debian-package', + + // fonts + 'psf' => 'application/x-font-linux-psf', + 'otf' => 'application/x-font-otf', + 'pcf' => 'application/x-font-pcf', + 'snf' => 'application/x-font-snf', + 'ttf' => 'application/x-font-ttf', + 'ttc' => 'application/x-font-ttf', + + // audio + 'mp3' => 'audio/mpeg', + 'amr' => 'audio/amr', + 'aac' => 'audio/x-aac', + 'aif' => 'audio/x-aiff', + 'aifc' => 'audio/x-aiff', + 'aiff' => 'audio/x-aiff', + 'wav' => 'audio/x-wav', + 'wma' => 'audio/x-ms-wma', + 'wax' => 'audio/x-ms-wax', + 'midi' => 'audio/midi', + 'mp4a' => 'audio/mp4', + 'ogg' => 'audio/ogg', + 'weba' => 'audio/webm', + 'ra' => 'audio/x-pn-realaudio', + 'ram' => 'audio/x-pn-realaudio', + 'rmp' => 'audio/x-pn-realaudio-plugin', + 'm3u' => 'audio/x-mpegurl', + + // video + 'flv' => 'video/x-flv', + 'qt' => 'video/quicktime', + 'mov' => 'video/quicktime', + 'avi' => 'video/x-msvideo', + 'mpg' => 'video/mpeg', + 'mpeg' => 'video/mpeg', + 'mpe' => 'video/mpeg', + 'm1v' => 'video/mpeg', + 'm2v' => 'video/mpeg', + '3gp' => 'video/3gpp', + '3g2' => 'video/3gpp2', + 'h261' => 'video/h261', + 'h263' => 'video/h263', + 'h264' => 'video/h264', + 'jpgv' => 'video/jpgv', + 'mp4' => 'video/mp4', + 'mp4v' => 'video/mp4', + 'mpg4' => 'video/mp4', + 'ogv' => 'video/ogg', + 'webm' => 'video/webm', + 'm4v' => 'video/x-m4v', + 'asf' => 'video/x-ms-asf', + 'asx' => 'video/x-ms-asf', + 'wm' => 'video/x-ms-wm', + 'wmv' => 'video/x-ms-wmv', + 'wmx' => 'video/x-ms-wmx', + 'wvx' => 'video/x-ms-wvx', + 'movie' => 'video/x-sgi-movie', + + // adobe + 'pdf' => 'application/pdf', + 'psd' => 'image/vnd.adobe.photoshop', + 'ai' => 'application/postscript', + 'eps' => 'application/postscript', + 'ps' => 'application/postscript', + + // ms office + 'doc' => 'application/msword', + 'dot' => 'application/msword', + 'rtf' => 'application/rtf', + 'xls' => 'application/vnd.ms-excel', + 'ppt' => 'application/vnd.ms-powerpoint', + 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', + 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + + // open office + 'odt' => 'application/vnd.oasis.opendocument.text', + 'ods' => 'application/vnd.oasis.opendocument.spreadsheet' + + ); + + $sExt = \MailSo\Base\Utils::GetFileExtension($sFileName); + if (0 < \strlen($sExt) && isset($aMimeTypes[$sExt])) + { + $sResult = $aMimeTypes[$sExt]; + } + + return $sResult; + } + + /** + * @param string $sContentType + * @param string $sFileName + * + * @return string + */ + public static function ContentTypeType($sContentType, $sFileName) + { + $sResult = ''; + $sContentType = \strtolower($sContentType); + if (0 === \strpos($sContentType, 'image/')) + { + $sResult = 'image'; + } + else + { + switch ($sContentType) + { + case 'application/zip': + case 'application/x-7z-compressed': + case 'application/x-rar-compressed': + case 'application/x-msdownload': + case 'application/vnd.ms-cab-compressed': + case 'application/x-gzip': + case 'application/x-bzip': + case 'application/x-bzip2': + case 'application/x-debian-package': + $sResult = 'archive'; + break; + case 'application/msword': + case 'application/rtf': + case 'application/vnd.ms-excel': + case 'application/vnd.ms-powerpoint': + case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': + case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': + case 'application/vnd.openxmlformats-officedocument.wordprocessingml.template': + case 'application/vnd.openxmlformats-officedocument.presentationml.presentation': + case 'application/vnd.oasis.opendocument.text': + case 'application/vnd.oasis.opendocument.spreadsheet': + $sResult = 'doc'; + break; + case 'application/pdf': + case 'application/x-pdf': + $sResult = 'pdf'; + break; + } + + if ('' === $sResult) + { + switch (\strtolower(\MailSo\Base\Utils::GetFileExtension($sFileName))) + { + case 'zip': + case '7z': + case 'rar': + $sResult = 'archive'; + break; + } + } + } + + return $sResult; + } + + /** + * @staticvar bool $bValidateAction + * + * @param int $iTimeToReset = 15 + * @param int $iTimeToAdd = 120 + * + * @return bool + */ + public static function ResetTimeLimit($iTimeToReset = 15, $iTimeToAdd = 120) + { + $iTime = \time(); + if ($iTime < \MailSo\Base\Loader::$InitTime + 5) + { + // do nothing first 5s + return true; + } + + static $bValidateAction = null; + static $iResetTimer = null; + + if (null === $bValidateAction) + { + $iResetTimer = 0; + + $sSafeMode = \strtolower(\trim(@\ini_get('safe_mode'))); + $bSafeMode = 'on' === $sSafeMode || '1' === $sSafeMode || 'true' === $sSafeMode; + + $bValidateAction = !$bSafeMode && \MailSo\Base\Utils::FunctionExistsAndEnabled('set_time_limit'); + } + + if ($bValidateAction && $iTimeToReset < $iTime - $iResetTimer) + { + $iResetTimer = $iTime; + if (!@\set_time_limit($iTimeToAdd)) + { + $bValidateAction = false; + return false; + } + + return true; + } + + return false; + } + + /** + * @param string $sText + * + * @return string + */ + public static function InlineRebuildStringToJsString($sText) + { + static $aJsonReplaces = array( + array('\\', "\n", "\t", "\r", '\b', "\f", '"'), + array('\\\\', '\\n', '\\t', '\\r', '\\b', '\\f', '\"') + ); + + return \str_replace('', '<\/script>', + \str_replace($aJsonReplaces[0], $aJsonReplaces[1], $sText)); + } + + /** + * @param array $aInput + */ + public static function ClearArrayUtf8Values(&$aInput) + { + if (\is_array($aInput)) + { + foreach ($aInput as $mKey => $mItem) + { + if (\is_string($mItem)) + { + $aInput[$mKey] = \MailSo\Base\Utils::Utf8Clear($mItem); + } + else if (\is_array($mItem)) + { + \MailSo\Base\Utils::ClearArrayUtf8Values($mItem); + $aInput[$mKey] = $mItem; + } + } + } + } + + /** + * @param mixed $mInput + * @param \MailSo\Log\Logger|null $oLogger = null + * + * @return string + */ + public static function Php2js($mInput, $oLogger = null) + { + static $iOpt = null; + if (null === $iOpt) + { + $iOpt = \defined('JSON_UNESCAPED_UNICODE') ? JSON_UNESCAPED_UNICODE : 0; + } + + $sResult = @\json_encode($mInput, $iOpt); + if (!\is_string($sResult) || '' === $sResult) + { + if (!$oLogger && \MailSo\Log\Logger::IsSystemEnabled()) + { + $oLogger = \MailSo\Config::$SystemLogger; + } + + if (!($oLogger instanceof \MailSo\Log\Logger)) + { + $oLogger = null; + } + + if ($oLogger) + { + $oLogger->Write('json_encode: '.\trim( + (\MailSo\Base\Utils::FunctionExistsAndEnabled('json_last_error') ? ' [Error Code: '.\json_last_error().']' : ''). + (\MailSo\Base\Utils::FunctionExistsAndEnabled('json_last_error_msg') ? ' [Error Message: '.\json_last_error_msg().']' : '') + ), \MailSo\Log\Enumerations\Type::WARNING, 'JSON' + ); + } + + if (\is_array($mInput)) + { + if ($oLogger) + { + $oLogger->WriteDump($mInput, \MailSo\Log\Enumerations\Type::INFO, 'JSON'); + $oLogger->Write('Trying to clear Utf8 before json_encode', \MailSo\Log\Enumerations\Type::INFO, 'JSON'); + } + + \MailSo\Base\Utils::ClearArrayUtf8Values($mInput); + $sResult = @\json_encode($mInput, $iOpt); + } + } + + return $sResult; + } + + /** + * @param string $sFileName + * + * @return string + */ + public static function ClearFileName($sFileName) + { + return \MailSo\Base\Utils::Trim(\MailSo\Base\Utils::ClearNullBite( + \MailSo\Base\Utils::StripSpaces( + \str_replace(array('"', '/', '\\', '*', '?', '<', '>', '|', ':'), ' ', $sFileName)))); + } + + /** + * @param string $sValue + * + * @return string + */ + public static function ClearXss($sValue) + { + return \MailSo\Base\Utils::Trim(\MailSo\Base\Utils::ClearNullBite( + \str_replace(array('"', '/', '\\', '*', '?', '<', '>', '|', ':'), ' ', $sValue))); + } + + /** + * @param string $sValue + * + * @return string + */ + public static function Trim($sValue) + { + return \trim(\preg_replace('/^[\x00-\x1F]+/u', '', + \preg_replace('/[\x00-\x1F]+$/u', '', \trim($sValue)))); + } + + /** + * @param string $sDir + * + * @return bool + */ + public static function RecRmDir($sDir) + { + if (@\is_dir($sDir)) + { + $aObjects = \scandir($sDir); + foreach ($aObjects as $sObject) + { + if ('.' !== $sObject && '..' !== $sObject) + { +// if ('dir' === \filetype($sDir.'/'.$sObject)) + if (\is_dir($sDir.'/'.$sObject)) + { + self::RecRmDir($sDir.'/'.$sObject); + } + else + { + @\unlink($sDir.'/'.$sObject); + } + } + } + + return @\rmdir($sDir); + } + + return false; + } + + /** + * @param string $sSource + * @param string $sDestination + */ + public static function CopyDir($sSource, $sDestination) + { + if (\is_dir($sSource)) + { + if (!\is_dir($sDestination)) + { + \mkdir($sDestination); + } + + $oDirectory = \dir($sSource); + if ($oDirectory) + { + while (false !== ($sRead = $oDirectory->read())) + { + if ('.' === $sRead || '..' === $sRead) + { + continue; + } + + $sPathDir = $sSource.'/'.$sRead; + if (\is_dir($sPathDir)) + { + \MailSo\Base\Utils::CopyDir($sPathDir, $sDestination.'/'.$sRead); + continue; + } + + \copy($sPathDir, $sDestination.'/'.$sRead); + } + + $oDirectory->close(); + } + } + } + + /** + * @param string $sTempPath + * @param int $iTime2Kill + * @param int $iNow + * + * @return bool + */ + public static function RecTimeDirRemove($sTempPath, $iTime2Kill, $iNow) + { + $iFileCount = 0; + + $sTempPath = rtrim($sTempPath, '\\/'); + if (@\is_dir($sTempPath)) + { + $rDirH = @\opendir($sTempPath); + if ($rDirH) + { + $bRemoveAllDirs = true; + while (($sFile = @\readdir($rDirH)) !== false) + { + if ('.' !== $sFile && '..' !== $sFile) + { + if (@\is_dir($sTempPath.'/'.$sFile)) + { + if (!\MailSo\Base\Utils::RecTimeDirRemove($sTempPath.'/'.$sFile, $iTime2Kill, $iNow)) + { + $bRemoveAllDirs = false; + } + } + else + { + $iFileCount++; + } + } + } + + @\closedir($rDirH); + } + + if ($iFileCount > 0) + { + if (\MailSo\Base\Utils::TimeFilesRemove($sTempPath, $iTime2Kill, $iNow)) + { + return @\rmdir($sTempPath); + } + } + else + { + return $bRemoveAllDirs ? @\rmdir($sTempPath) : false; + } + + return false; + } + + return true; + } + + /** + * @param string $sTempPath + * @param int $iTime2Kill + * @param int $iNow + */ + public static function TimeFilesRemove($sTempPath, $iTime2Kill, $iNow) + { + $bResult = true; + + $sTempPath = rtrim($sTempPath, '\\/'); + if (@\is_dir($sTempPath)) + { + $rDirH = @\opendir($sTempPath); + if ($rDirH) + { + while (($sFile = @\readdir($rDirH)) !== false) + { + if ($sFile !== '.' && $sFile !== '..') + { + if ($iNow - \filemtime($sTempPath.'/'.$sFile) > $iTime2Kill) + { + @\unlink($sTempPath.'/'.$sFile); + } + else + { + $bResult = false; + } + } + } + + @\closedir($rDirH); + } + } + + return $bResult; + } + + /** + * @param string $sUtfString + * @param int $iLength + * + * @return string + */ + public static function Utf8Truncate($sUtfString, $iLength) + { + if (\strlen($sUtfString) <= $iLength) + { + return $sUtfString; + } + + while ($iLength >= 0) + { + if ((\ord($sUtfString[$iLength]) < 0x80) || (\ord($sUtfString[$iLength]) >= 0xC0)) + { + return \substr($sUtfString, 0, $iLength); + } + + $iLength--; + } + + return ''; + } + + /** + * @param string $sUtfString + * @param string $sReplaceOn = '' + * + * @return string + */ + public static function Utf8Clear($sUtfString, $sReplaceOn = '') + { + if ('' === $sUtfString) + { + return $sUtfString; + } + + $sUtfString = \preg_replace(\MailSo\Base\Utils::$sValidUtf8Regexp, '$1', $sUtfString); + + $sUtfString = \preg_replace( + '/\xE0[\x80-\x9F][\x80-\xBF]'. + '|\xEF\xBF\xBF'. + '|\xED[\xA0-\xBF][\x80-\xBF]/S', $sReplaceOn, $sUtfString); + + $sUtfString = \preg_replace('/\xEF\xBF\xBD/', '?', $sUtfString); + + $sNewUtfString = false; + if (false === $sNewUtfString && \MailSo\Base\Utils::IsMbStringSupported()) + { + $sNewUtfString = \MailSo\Base\Utils::MbConvertEncoding($sUtfString, 'UTF-8', 'UTF-8'); + } + + if (false === $sNewUtfString && \MailSo\Base\Utils::IsIconvSupported()) + { + $sNewUtfString = \MailSo\Base\Utils::IconvConvertEncoding($sUtfString, 'UTF-8', 'UTF-8'); + } + + if (false !== $sNewUtfString) + { + $sUtfString = $sNewUtfString; + } + + return $sUtfString; + } + + /** + * @param string $sUtfString + * + * @return bool + */ + public static function IsRTL($sUtfString) + { + // \x{0591}-\x{05F4} - Hebrew + // \x{0600}-\x{068F} - Arabic + // \x{0750}-\x{077F} - Arabic + // \x{08A0}-\x{08FF} - Arabic + // \x{103A0}-\x{103DF} - Old Persian + return 0 < (int) preg_match('/[\x{0591}-\x{05F4}\x{0600}-\x{068F}\x{0750}-\x{077F}\x{08A0}-\x{08FF}\x{103A0}-\x{103DF}]/u', $sUtfString); + } + + /** + * @param string $sString + * + * @return string + */ + public static function Base64Decode($sString) + { + $sResultString = \base64_decode($sString, true); + if (false === $sResultString) + { + $sString = \str_replace(array(' ', "\r", "\n", "\t"), '', $sString); + $sString = \preg_replace('/[^a-zA-Z0-9=+\/](.*)$/', '', $sString); + + if (false !== \strpos(\trim(\trim($sString), '='), '=')) + { + $sString = \preg_replace('/=([^=])/', '= $1', $sString); + $aStrings = \explode(' ', $sString); + foreach ($aStrings as $iIndex => $sParts) + { + $aStrings[$iIndex] = \base64_decode($sParts); + } + + $sResultString = \implode('', $aStrings); + } + else + { + $sResultString = \base64_decode($sString); + } + } + + return $sResultString; + } + + /** + * @param string $sValue + * + * @return string + */ + public static function UrlSafeBase64Encode($sValue) + { + return \rtrim(\strtr(\base64_encode($sValue), '+/', '-_'), '='); + } + + /** + * @param string $sValue + * + * @return string + */ + public static function UrlSafeBase64Decode($sValue) + { + $sValue = \rtrim(\strtr($sValue, '-_.', '+/='), '='); + return \MailSo\Base\Utils::Base64Decode(\str_pad($sValue, \strlen($sValue) + (\strlen($sValue) % 4), '=', STR_PAD_RIGHT)); + } + + /** + * @param string $sSequence + * + * @return array + */ + public static function ParseFetchSequence($sSequence) + { + $aResult = array(); + $sSequence = \trim($sSequence); + if (0 < \strlen($sSequence)) + { + $aSequence = \explode(',', $sSequence); + foreach ($aSequence as $sItem) + { + if (false === \strpos($sItem, ':')) + { + $aResult[] = (int) $sItem; + } + else + { + $aItems = \explode(':', $sItem); + $iMax = \max($aItems[0], $aItems[1]); + + for ($iIndex = $aItems[0]; $iIndex <= $iMax; $iIndex++) + { + $aResult[] = (int) $iIndex; + } + } + } + } + + return $aResult; + } + /** + * @param array $aSequence + * + * @return string + */ + public static function PrepearFetchSequence($aSequence) + { + $aResult = array(); + if (\is_array($aSequence) && 0 < \count($aSequence)) + { + $iStart = null; + $iPrev = null; + + foreach ($aSequence as $sItem) + { + // simple protection + if (false !== \strpos($sItem, ':')) + { + $aResult[] = $sItem; + continue; + } + + $iItem = (int) $sItem; + if (null === $iStart || null === $iPrev) + { + $iStart = $iItem; + $iPrev = $iItem; + continue; + } + + if ($iPrev === $iItem - 1) + { + $iPrev = $iItem; + } + else + { + $aResult[] = $iStart === $iPrev ? $iStart : $iStart.':'.$iPrev; + $iStart = $iItem; + $iPrev = $iItem; + } + } + + if (null !== $iStart && null !== $iPrev) + { + $aResult[] = $iStart === $iPrev ? $iStart : $iStart.':'.$iPrev; + } + } + + return \implode(',', $aResult); + } + + /** + * + * @param resource $fResource + * @param int $iBufferLen = 8192 + * + * @return bool + */ + public static function FpassthruWithTimeLimitReset($fResource, $iBufferLen = 8192) + { + $bResult = false; + if (\is_resource($fResource)) + { + while (!\feof($fResource)) + { + $sBuffer = @\fread($fResource, $iBufferLen); + if (false !== $sBuffer) + { + echo $sBuffer; + \MailSo\Base\Utils::ResetTimeLimit(); + continue; + } + + break; + } + + $bResult = true; + } + + return $bResult; + } + + /** + * @param resource $rRead + * @param array $aWrite + * @param int $iBufferLen = 8192 + * @param bool $bResetTimeLimit = true + * @param bool $bFixCrLf = false + * @param bool $bRewindOnComplete = false + * + * @return int|bool + */ + public static function MultipleStreamWriter($rRead, $aWrite, $iBufferLen = 8192, $bResetTimeLimit = true, $bFixCrLf = false, $bRewindOnComplete = false) + { + $mResult = false; + if ($rRead && \is_array($aWrite) && 0 < \count($aWrite)) + { + $mResult = 0; + while (!\feof($rRead)) + { + $sBuffer = \fread($rRead, $iBufferLen); + if (false === $sBuffer) + { + $mResult = false; + break; + } + + if (0 === $iBufferLen || '' === $sBuffer) + { + break; + } + + if ($bFixCrLf) + { + $sBuffer = \str_replace("\n", "\r\n", \str_replace("\r", '', $sBuffer)); + } + + $mResult += \strlen($sBuffer); + + foreach ($aWrite as $rWriteStream) + { + $mWriteResult = \fwrite($rWriteStream, $sBuffer); + if (false === $mWriteResult) + { + $mResult = false; + break 2; + } + } + + if ($bResetTimeLimit) + { + \MailSo\Base\Utils::ResetTimeLimit(); + } + } + } + + if ($mResult && $bRewindOnComplete) + { + foreach ($aWrite as $rWriteStream) + { + if (\is_resource($rWriteStream)) + { + @\rewind($rWriteStream); + } + } + } + + return $mResult; + } + + /** + * @param string $sUtfModifiedString + * + * @return string + */ + public static function ModifiedToPlainUtf7($sUtfModifiedString) + { + $sUtf = ''; + $bBase = false; + + for ($iIndex = 0, $iLen = \strlen($sUtfModifiedString); $iIndex < $iLen; $iIndex++) + { + if ('&' === $sUtfModifiedString[$iIndex]) + { + if (isset($sUtfModifiedString[$iIndex+1]) && '-' === $sUtfModifiedString[$iIndex + 1]) + { + $sUtf .= '&'; + $iIndex++; + } + else + { + $sUtf .= '+'; + $bBase = true; + } + } + else if ($sUtfModifiedString[$iIndex] == '-' && $bBase) + { + $bBase = false; + } + else + { + if ($bBase && ',' === $sUtfModifiedString[$iIndex]) + { + $sUtf .= '/'; + } + else if (!$bBase && '+' === $sUtfModifiedString[$iIndex]) + { + $sUtf .= '+-'; + } + else + { + $sUtf .= $sUtfModifiedString[$iIndex]; + } + } + } + + return $sUtf; + } + + /** + * @param string $sStr + * + * @return string|bool + */ + public static function Utf7ModifiedToUtf8($sStr) + { + $aArray = array(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,62, 63,-1,-1,-1,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,-1,0,1,2,3,4,5,6,7,8,9, + 10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, + 41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1); + + $sResult = ''; + $bError = false; + $iLen = \strlen($sStr); + + for ($iIndex = 0; $iLen > 0; $iIndex++, $iLen--) + { + $sChar = $sStr{$iIndex}; + if ($sChar == '&') + { + $iIndex++; + $iLen--; + + $sChar = isset($sStr{$iIndex}) ? $sStr{$iIndex} : null; + if ($sChar === null) + { + break; + } + + if ($iLen && $sChar == '-') + { + $sResult .= '&'; + continue; + } + + $iCh = 0; + $iK = 10; + for (; $iLen > 0; $iIndex++, $iLen--) + { + $sChar = $sStr{$iIndex}; + + $iB = $aArray[\ord($sChar)]; + if ((\ord($sChar) & 0x80) || $iB == -1) + { + break; + } + + if ($iK > 0) + { + $iCh |= $iB << $iK; + $iK -= 6; + } + else + { + $iCh |= $iB >> (-$iK); + if ($iCh < 0x80) + { + if (0x20 <= $iCh && $iCh < 0x7f) + { + return $bError; + } + + $sResult .= \chr($iCh); + } + else if ($iCh < 0x800) + { + $sResult .= \chr(0xc0 | ($iCh >> 6)); + $sResult .= \chr(0x80 | ($iCh & 0x3f)); + } + else + { + $sResult .= \chr(0xe0 | ($iCh >> 12)); + $sResult .= \chr(0x80 | (($iCh >> 6) & 0x3f)); + $sResult .= \chr(0x80 | ($iCh & 0x3f)); + } + + $iCh = ($iB << (16 + $iK)) & 0xffff; + $iK += 10; + } + } + + if (($iCh || $iK < 6) || + (!$iLen || $sChar != '-') || + ($iLen > 2 && '&' === $sStr{$iIndex+1} && '-' !== $sStr{$iIndex+2})) + { + return $bError; + } + } + else if (\ord($sChar) < 0x20 || \ord($sChar) >= 0x7f) + { + return $bError; + } + else + { + $sResult .= $sChar; + } + } + + return $sResult; + } + + /** + * @param string $sStr + * + * @return string|bool + */ + public static function Utf8ToUtf7Modified($sStr) + { + $sArray = array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S', + 'T','U','V','W','X','Y','Z', 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o', + 'p','q','r','s','t','u','v','w','x','y','z', '0','1','2','3','4','5','6','7','8','9','+',','); + + $sLen = \strlen($sStr); + $bIsB = false; + $iIndex = $iN = 0; + $sReturn = ''; + $bError = false; + $iCh = $iB = $iK = 0; + + while ($sLen) + { + $iC = \ord($sStr{$iIndex}); + if ($iC < 0x80) + { + $iCh = $iC; + $iN = 0; + } + else if ($iC < 0xc2) + { + return $bError; + } + else if ($iC < 0xe0) + { + $iCh = $iC & 0x1f; + $iN = 1; + } + else if ($iC < 0xf0) + { + $iCh = $iC & 0x0f; + $iN = 2; + } + else if ($iC < 0xf8) + { + $iCh = $iC & 0x07; + $iN = 3; + } + else if ($iC < 0xfc) + { + $iCh = $iC & 0x03; + $iN = 4; + } + else if ($iC < 0xfe) + { + $iCh = $iC & 0x01; + $iN = 5; + } + else + { + return $bError; + } + + $iIndex++; + $sLen--; + + if ($iN > $sLen) + { + return $bError; + } + + for ($iJ = 0; $iJ < $iN; $iJ++) + { + $iO = \ord($sStr{$iIndex+$iJ}); + if (($iO & 0xc0) != 0x80) + { + return $bError; + } + + $iCh = ($iCh << 6) | ($iO & 0x3f); + } + + if ($iN > 1 && !($iCh >> ($iN * 5 + 1))) + { + return $bError; + } + + $iIndex += $iN; + $sLen -= $iN; + + if ($iCh < 0x20 || $iCh >= 0x7f) + { + if (!$bIsB) + { + $sReturn .= '&'; + $bIsB = true; + $iB = 0; + $iK = 10; + } + + if ($iCh & ~0xffff) + { + $iCh = 0xfffe; + } + + $sReturn .= $sArray[($iB | $iCh >> $iK)]; + $iK -= 6; + for (; $iK >= 0; $iK -= 6) + { + $sReturn .= $sArray[(($iCh >> $iK) & 0x3f)]; + } + + $iB = ($iCh << (-$iK)) & 0x3f; + $iK += 16; + } + else + { + if ($bIsB) + { + if ($iK > 10) + { + $sReturn .= $sArray[$iB]; + } + $sReturn .= '-'; + $bIsB = false; + } + + $sReturn .= \chr($iCh); + if ('&' === \chr($iCh)) + { + $sReturn .= '-'; + } + } + } + + if ($bIsB) + { + if ($iK > 10) + { + $sReturn .= $sArray[$iB]; + } + + $sReturn .= '-'; + } + + return $sReturn; + } + + /** + * @param string|array $mFunctionNameOrNames + * + * @return bool + */ + public static function FunctionExistsAndEnabled($mFunctionNameOrNames) + { + static $aCache = null; + + if (\is_array($mFunctionNameOrNames)) + { + foreach ($mFunctionNameOrNames as $sFunctionName) + { + if (!\MailSo\Base\Utils::FunctionExistsAndEnabled($sFunctionName)) + { + return false; + } + } + + return true; + } + + if (empty($mFunctionNameOrNames) || !\function_exists($mFunctionNameOrNames) || !\is_callable($mFunctionNameOrNames)) + { + return false; + } + + if (null === $aCache) + { + $sDisableFunctions = @\ini_get('disable_functions'); + $sDisableFunctions = \is_string($sDisableFunctions) && 0 < \strlen($sDisableFunctions) ? $sDisableFunctions : ''; + + $aCache = \explode(',', $sDisableFunctions); + $aCache = \is_array($aCache) && 0 < \count($aCache) ? $aCache : array(); + + if (\extension_loaded('suhosin')) + { + $sSuhosin = @\ini_get('suhosin.executor.func.blacklist'); + $sSuhosin = \is_string($sSuhosin) && 0 < \strlen($sSuhosin) ? $sSuhosin : ''; + + $aSuhosinCache = \explode(',', $sSuhosin); + $aSuhosinCache = \is_array($aSuhosinCache) && 0 < \count($aSuhosinCache) ? $aSuhosinCache : array(); + + if (0 < \count($aSuhosinCache)) + { + $aCache = \array_merge($aCache, $aSuhosinCache); + $aCache = \array_unique($aCache); + } + } + } + + return !\in_array($mFunctionNameOrNames, $aCache); + } + + /** + * @param string $mValue + * + * @return string + */ + public static function ClearNullBite($mValue) + { + return \str_replace('%00', '', $mValue); + } + + /** + * @param mixed $mValue + * @param bool $bClearNullBite = false + * + * @return mixed + */ + public static function StripSlashesValue($mValue, $bClearNullBite = false) + { + static $bIsMagicQuotesOn = null; + if (null === $bIsMagicQuotesOn) + { + $bIsMagicQuotesOn = (bool) @\ini_get('magic_quotes_gpc'); + } + + if (!$bIsMagicQuotesOn) + { + return $bClearNullBite && \is_string($mValue) ? \MailSo\Base\Utils::ClearNullBite($mValue) : $mValue; + } + + $sType = \gettype($mValue); + if ('string' === $sType) + { + return \stripslashes($bClearNullBite ? \MailSo\Base\Utils::ClearNullBite($mValue) : $mValue); + } + else if ('array' === $sType) + { + $aReturnValue = array(); + $mValueKeys = \array_keys($mValue); + foreach ($mValueKeys as $sKey) + { + $aReturnValue[$sKey] = \MailSo\Base\Utils::StripSlashesValue($mValue[$sKey], $bClearNullBite); + } + + return $aReturnValue; + } + + return $mValue; + } + + /** + * @param string $sStr + * + * @return string + */ + public static function CharsetDetect($sStr) + { + $mResult = ''; + if (!\MailSo\Base\Utils::IsAscii($sStr)) + { + $mResult = \MailSo\Base\Utils::IsMbStringSupported() && + \MailSo\Base\Utils::FunctionExistsAndEnabled('mb_detect_encoding') ? + @\mb_detect_encoding($sStr, 'auto', true) : false; + + if (false === $mResult && \MailSo\Base\Utils::IsIconvSupported()) + { + $mResult = \md5(@\iconv('utf-8', 'utf-8//IGNORE', $sStr)) === \md5($sStr) ? 'utf-8' : ''; + } + } + + return \is_string($mResult) && 0 < \strlen($mResult) ? $mResult : ''; + } + + /** + * @param string $sAdditionalSalt = '' + * + * @return string + */ + public static function Md5Rand($sAdditionalSalt = '') + { + return \md5(\microtime(true).\rand(10000, 99999). + \md5($sAdditionalSalt).\rand(10000, 99999).\microtime(true)); + } + + /** + * @param string $sAdditionalSalt = '' + * + * @return string + */ + public static function Sha1Rand($sAdditionalSalt = '') + { + return \sha1(\microtime(true).\rand(10000, 99999). + \sha1($sAdditionalSalt).\rand(10000, 99999).\microtime(true)); + } + + /** + * @param string $sData + * @param string $sKey + * + * @return string + */ + public static function Hmac($sData, $sKey) + { + if (\function_exists('hash_hmac')) + { + return \hash_hmac('md5', $sData, $sKey); + } + + $iLen = 64; + if ($iLen < \strlen($sKey)) + { + $sKey = \pack('H*', \md5($sKey)); + } + + $sKey = \str_pad($sKey, $iLen, \chr(0x00)); + $sIpad = \str_pad('', $iLen, \chr(0x36)); + $sOpad = \str_pad('', $iLen, \chr(0x5c)); + + return \md5(($sKey ^ $sOpad).\pack('H*', \md5(($sKey ^ $sIpad).$sData))); + } + + /** + * @param string $sDomain + * @param bool $bSimple = false + * + * @return bool + */ + public static function ValidateDomain($sDomain, $bSimple = false) + { + $aMatch = array(); + if ($bSimple) + { + return \preg_match('/.+(\.[a-zA-Z]+)$/', $sDomain, $aMatch) && !empty($aMatch[1]); + } + + return \preg_match('/.+(\.[a-zA-Z]+)$/', $sDomain, $aMatch) && !empty($aMatch[1]) && \in_array($aMatch[1], \explode(' ', + '.academy .actor .agency .audio .bar .beer .bike .blue .boutique .cab .camera .camp .capital .cards .careers .cash .catering .center .cheap .city .cleaning .clinic .clothing .club .coffee .community .company .computer .construction .consulting .contractors .cool .credit .dance .dating .democrat .dental .diamonds .digital .direct .directory .discount .domains .education .email .energy .equipment .estate .events .expert .exposed .fail .farm .fish .fitness .florist .fund .futbol .gallery .gift .glass .graphics .guru .help .holdings .holiday .host .hosting .house .institute .international .kitchen .land .life .lighting .limo .link .management .market .marketing .media .menu .moda .partners .parts .photo .photography .photos .pics .pink .press .productions .pub .red .rentals .repair .report .rest .sexy .shoes .social .solar .solutions .space .support .systems .tattoo .tax .technology .tips .today .tools .town .toys .trade .training .university .uno .vacations .vision .vodka .voyage .watch .webcam .wiki .work .works .wtf .zone .aero .asia .biz .cat .com .coop .edu .gov .info .int .jobs .mil .mobi .museum .name .net .org .pro .tel .travel .xxx .xyz '. + '.ac .ad .ae .af .ag .ai .al .am .an .ao .aq .ar .as .at .au .aw .ax .az .ba .bb .bd .be .bf .bg .bh .bi .bj .bm .bn .bo .br .bs .bt .bv .bw .by .bz .ca .cc .cd .cf .cg .ch .ci .ck .cl .cm .cn .co .cr .cs .cu .cv .cx .cy .cz .dd .de .dj .dk .dm .do .dz .ec .ee .eg .er .es .et .eu .fi .fj .fk .fm .fo .fr .ga .gb .gd .ge .gf .gg .gh .gi .gl .gm .gn .gp .gq .gr .gs .gt .gu .gw .gy .hk .hm .hn .hr .ht .hu .id .ie .il .im .in .io .iq .ir .is .it .je .jm .jo .jp .ke .kg .kh .ki .km .kn .kp .kr .kw .ky .kz .la .lb .lc .li .lk .lr .ls .lt .lu .lv .ly .ma .mc .md .me .mg .mh .mk .ml .mm .mn .mo .mp .mq .mr .ms .mt .mu .mv .mw .mx .my .mz .na .nc .ne .nf .ng .ni .nl .no .np .nr .nu .nz .om .pa .pe .pf .pg .ph .pk .pl .pm .pn .pr .ps .pt .pw .py .qa .re .ro .rs .ru . .rw .sa .sb .sc .sd .se .sg .sh .si .sj .sk .sl .sm .sn .so .sr .st .su .sv .sy .sz .tc .td .tf .tg .th .tj .tk .tl .tm .tn .to .tp .tr .tt .tv .tw .tz .ua .ug .uk .us .uy .uz .va .vc .ve .vg .vi .vn .vu .wf .ws .ye .yt .za .zm .zw' + )); + } + + /** + * @param string $sIp + * + * @return bool + */ + public static function ValidateIP($sIp) + { + return !empty($sIp) && $sIp === @\filter_var($sIp, FILTER_VALIDATE_IP); + } + + /** + * @return \Net_IDNA2 + */ + private static function idn() + { + static $oIdn = null; + if (null === $oIdn) + { + include_once MAILSO_LIBRARY_ROOT_PATH.'Vendors/Net/IDNA2.php'; + $oIdn = new \Net_IDNA2(); + $oIdn->setParams('utf8', true); + } + + return $oIdn; + } + + /** + * @param string $sStr + * @param bool $bLowerIfAscii = false + * + * @return string + */ + public static function IdnToUtf8($sStr, $bLowerIfAscii = false) + { + if (0 < \strlen($sStr) && \preg_match('/(^|\.|@)xn--/i', $sStr)) + { + try + { + $sStr = self::idn()->decode($sStr); + } + catch (\Exception $oException) {} + } + + return $bLowerIfAscii ? \MailSo\Base\Utils::StrMailDomainToLowerIfAscii($sStr) : $sStr; + } + + /** + * @param string $sStr + * @param bool $bLowerIfAscii = false + * + * @return string + */ + public static function IdnToAscii($sStr, $bLowerIfAscii = false) + { + $sStr = $bLowerIfAscii ? \MailSo\Base\Utils::StrMailDomainToLowerIfAscii($sStr) : $sStr; + + $sUser = ''; + $sDomain = $sStr; + if (false !== \strpos($sStr, '@')) + { + $sUser = \MailSo\Base\Utils::GetAccountNameFromEmail($sStr); + $sDomain = \MailSo\Base\Utils::GetDomainFromEmail($sStr); + } + + if (0 < \strlen($sDomain) && \preg_match('/[^\x20-\x7E]/', $sDomain)) + { + try + { + $sDomain = self::idn()->encode($sDomain); + } + catch (\Exception $oException) {} + } + + return ('' === $sUser ? '' : $sUser.'@').$sDomain; + } + + /** + * @param string $sHash + * @param string $sSalt + * + * @return int + */ + public static function HashToId($sHash, $sSalt = '') + { + $sData = $sHash ? @\MailSo\Base\Crypt::XxteaDecrypt(\hex2bin($sHash), \md5($sSalt)) : null; + + $aMatch = array(); + if ($sData && preg_match('/^id:(\d+)$/', $sData, $aMatch) && isset($aMatch[1])) + { + return is_numeric($aMatch[1]) ? (int) $aMatch[1] : null; + } + + return null; + } + + /** + * @param int $iID + * @param string $sSalt + * + * @return string + */ + public static function IdToHash($iID, $sSalt = '') + { + return is_int($iID) ? + \bin2hex(\MailSo\Base\Crypt::XxteaEncrypt('id:'.$iID, \md5($sSalt))) : null + ; + } + + /** + * @param string $sPassword + * + * @return bool + */ + public static function PasswordWeaknessCheck($sPassword) + { + $sPassword = \trim($sPassword); + if (6 > \strlen($sPassword)) + { + return false; + } + + $sLine = 'password 123.456 12345678 abc123 qwerty monkey letmein dragon 111.111 baseball iloveyou trustno1 1234567 sunshine master 123.123 welcome shadow ashley football jesus michael ninja mustang password1 123456 123456789 qwerty 111111 1234567 666666 12345678 7777777 123321 654321 1234567890 123123 555555 vkontakte gfhjkm 159753 777777 temppassword qazwsx 1q2w3e 1234 112233 121212 qwertyuiop qq18ww899 987654321 12345 zxcvbn zxcvbnm 999999 samsung ghbdtn 1q2w3e4r 1111111 123654 159357 131313 qazwsxedc 123qwe 222222 asdfgh 333333 9379992 asdfghjkl 4815162342 12344321 88888888 11111111 knopka 789456 qwertyu 1q2w3e4r5t iloveyou vfhbyf marina password qweasdzxc 10203 987654 yfnfif cjkysirj nikita 888888 vfrcbv k.,jdm qwertyuiop[] qwe123 qweasd natasha 123123123 fylhtq q1w2e3 stalker 1111111111 q1w2e3r4 nastya 147258369 147258 fyfcnfcbz 1234554321 1qaz2wsx andrey 111222 147852 genius sergey 7654321 232323 123789 fktrcfylh spartak admin test 123 azerty abc123 lol123 easytocrack1 hello saravn holysh!t test123 tundra_cool2 456 dragon thomas killer root 1111 pass master aaaaaa a monkey daniel asdasd e10adc3949ba59abbe56e057f20f883e changeme computer jessica letmein mirage loulou lol superman shadow admin123 secret administrator sophie kikugalanetroot doudou liverpool hallo sunshine charlie parola 100827092 michael andrew password1 fuckyou matrix cjmasterinf internet hallo123 eminem demo gewinner pokemon abcd1234 guest ngockhoa martin sandra asdf hejsan george qweqwe lollipop lovers q1q1q1 tecktonik naruto 12 password12 password123 password1234 password12345 password123456 password1234567 password12345678 password123456789 000000 maximius 123abc baseball1 football1 soccer princess slipknot 11111 nokia super star 666999 12341234 1234321 135790 159951 212121 zzzzzz 121314 134679 142536 19921992 753951 7007 1111114 124578 19951995 258456 qwaszx zaqwsx 55555 77777 54321 qwert 22222 33333 99999 88888 66666'; + return false === \strpos($sLine, \strtolower($sPassword)); + } +} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Base/Validator.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Base/Validator.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Base/Validator.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Base/Validator.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Cache/CacheClient.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Cache/CacheClient.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Cache/CacheClient.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Cache/CacheClient.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Cache/DriverInterface.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Cache/DriverInterface.php similarity index 93% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Cache/DriverInterface.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Cache/DriverInterface.php index 4789cd6c19aaf1c620708aa46eeec5522593f006..8751ba1db31ac9b11f9f64c3f26c6104cde75272 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Cache/DriverInterface.php +++ b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Cache/DriverInterface.php @@ -1,48 +1,48 @@ -oImapResponse = $oImapResponse; - $this->aEnvelopeCache = null; - } - - /** - * @param \MailSo\Imap\Response $oImapResponse - * @return \MailSo\Imap\FetchResponse - */ - public static function NewInstance($oImapResponse) - { - return new self($oImapResponse); - } - - /** - * @param bool $bForce = false - * - * @return array|null - */ - public function GetEnvelope($bForce = false) - { - if (null === $this->aEnvelopeCache || $bForce) - { - $this->aEnvelopeCache = $this->GetFetchValue(Enumerations\FetchType::ENVELOPE); - } - return $this->aEnvelopeCache; - } - - /** - * @param int $iIndex - * @param mixed $mNullResult = null - * - * @return mixed - */ - public function GetFetchEnvelopeValue($iIndex, $mNullResult) - { - return self::findEnvelopeIndex($this->GetEnvelope(), $iIndex, $mNullResult); - } - - /** - * @param int $iIndex - * @param string $sParentCharset = \MailSo\Base\Enumerations\Charset::ISO_8859_1 - * - * @return \MailSo\Mime\EmailCollection|null - */ - public function GetFetchEnvelopeEmailCollection($iIndex, $sParentCharset = \MailSo\Base\Enumerations\Charset::ISO_8859_1) - { - $oResult = null; - $aEmails = $this->GetFetchEnvelopeValue($iIndex, null); - if (is_array($aEmails) && 0 < count($aEmails)) - { - $oResult = \MailSo\Mime\EmailCollection::NewInstance(); - foreach ($aEmails as $aEmailItem) - { - if (is_array($aEmailItem) && 4 === count($aEmailItem)) - { - $sDisplayName = \MailSo\Base\Utils::DecodeHeaderValue( - self::findEnvelopeIndex($aEmailItem, 0, ''), $sParentCharset); - -// $sRemark = \MailSo\Base\Utils::DecodeHeaderValue( -// self::findEnvelopeIndex($aEmailItem, 1, ''), $sParentCharset); - - $sLocalPart = self::findEnvelopeIndex($aEmailItem, 2, ''); - $sDomainPart = self::findEnvelopeIndex($aEmailItem, 3, ''); - - if (0 < strlen($sLocalPart) && 0 < strlen($sDomainPart)) - { - $oResult->Add( - \MailSo\Mime\Email::NewInstance($sLocalPart.'@'.$sDomainPart, $sDisplayName) - ); - } - } - } - } - - return $oResult; - } - - /** - * @param string $sRfc822SubMimeIndex = '' - * - * @return \MailSo\Imap\BodyStructure|null - */ - public function GetFetchBodyStructure($sRfc822SubMimeIndex = '') - { - $oBodyStructure = null; - $aBodyStructureArray = $this->GetFetchValue(Enumerations\FetchType::BODYSTRUCTURE); - - if (is_array($aBodyStructureArray)) - { - if (0 < strlen($sRfc822SubMimeIndex)) - { - $oBodyStructure = BodyStructure::NewInstanceFromRfc822SubPart($aBodyStructureArray, $sRfc822SubMimeIndex); - } - else - { - $oBodyStructure = BodyStructure::NewInstance($aBodyStructureArray); - } - } - - return $oBodyStructure; - } - - /** - * @param string $sFetchItemName - * - * @return mixed - */ - public function GetFetchValue($sFetchItemName) - { - $mReturn = null; - $bNextIsValue = false; - - if (Enumerations\FetchType::INDEX === $sFetchItemName) - { - $mReturn = $this->oImapResponse->ResponseList[1]; - } - else if (isset($this->oImapResponse->ResponseList[3]) && \is_array($this->oImapResponse->ResponseList[3])) - { - foreach ($this->oImapResponse->ResponseList[3] as $mItem) - { - if ($bNextIsValue) - { - $mReturn = $mItem; - break; - } - - if ($sFetchItemName === $mItem) - { - $bNextIsValue = true; - } - } - } - - return $mReturn; - } - - /** - * @param string $sRfc822SubMimeIndex = '' - * - * @return string - */ - public function GetHeaderFieldsValue($sRfc822SubMimeIndex = '') - { - $sReturn = ''; - $bNextIsValue = false; - - $sRfc822SubMimeIndex = 0 < \strlen($sRfc822SubMimeIndex) ? ''.$sRfc822SubMimeIndex.'.' : ''; - - if (isset($this->oImapResponse->ResponseList[3]) && \is_array($this->oImapResponse->ResponseList[3])) - { - foreach ($this->oImapResponse->ResponseList[3] as $mItem) - { - if ($bNextIsValue) - { - $sReturn = (string) $mItem; - break; - } - - if (\is_string($mItem) && ( - $mItem === 'BODY['.$sRfc822SubMimeIndex.'HEADER]' || - 0 === \strpos($mItem, 'BODY['.$sRfc822SubMimeIndex.'HEADER.FIELDS') || - $mItem === 'BODY['.$sRfc822SubMimeIndex.'MIME]')) - { - $bNextIsValue = true; - } - } - } - - return $sReturn; - } - - private static function findFetchUidAndSize($aList) - { - $bUid = false; - $bSize = false; - if (is_array($aList)) - { - foreach ($aList as $mItem) - { - if (\MailSo\Imap\Enumerations\FetchType::UID === $mItem) - { - $bUid = true; - } - else if (\MailSo\Imap\Enumerations\FetchType::RFC822_SIZE === $mItem) - { - $bSize = true; - } - } - } - - return $bUid && $bSize; - } - - /** - * @param \MailSo\Imap\Response $oImapResponse - * - * @return bool - */ - public static function IsValidFetchImapResponse($oImapResponse) - { - return ( - $oImapResponse - && true !== $oImapResponse->IsStatusResponse - && \MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oImapResponse->ResponseType - && 3 < count($oImapResponse->ResponseList) && 'FETCH' === $oImapResponse->ResponseList[2] - && is_array($oImapResponse->ResponseList[3]) - ); - } - - /** - * @param \MailSo\Imap\Response $oImapResponse - * - * @return bool - */ - public static function IsNotEmptyFetchImapResponse($oImapResponse) - { - return ( - $oImapResponse - && self::IsValidFetchImapResponse($oImapResponse) - && isset($oImapResponse->ResponseList[3]) - && self::findFetchUidAndSize($oImapResponse->ResponseList[3]) - ); - } - - /** - * @param array $aEnvelope - * @param int $iIndex - * @param mixed $mNullResult = null - * - * @return mixed - */ - private static function findEnvelopeIndex($aEnvelope, $iIndex, $mNullResult) - { - return (isset($aEnvelope[$iIndex]) && 'NIL' !== $aEnvelope[$iIndex] && '' !== $aEnvelope[$iIndex]) - ? $aEnvelope[$iIndex] : $mNullResult; - } -} +oImapResponse = $oImapResponse; + $this->aEnvelopeCache = null; + } + + /** + * @param \MailSo\Imap\Response $oImapResponse + * @return \MailSo\Imap\FetchResponse + */ + public static function NewInstance($oImapResponse) + { + return new self($oImapResponse); + } + + /** + * @param bool $bForce = false + * + * @return array|null + */ + public function GetEnvelope($bForce = false) + { + if (null === $this->aEnvelopeCache || $bForce) + { + $this->aEnvelopeCache = $this->GetFetchValue(Enumerations\FetchType::ENVELOPE); + } + return $this->aEnvelopeCache; + } + + /** + * @param int $iIndex + * @param mixed $mNullResult = null + * + * @return mixed + */ + public function GetFetchEnvelopeValue($iIndex, $mNullResult) + { + return self::findEnvelopeIndex($this->GetEnvelope(), $iIndex, $mNullResult); + } + + /** + * @param int $iIndex + * @param string $sParentCharset = \MailSo\Base\Enumerations\Charset::ISO_8859_1 + * + * @return \MailSo\Mime\EmailCollection|null + */ + public function GetFetchEnvelopeEmailCollection($iIndex, $sParentCharset = \MailSo\Base\Enumerations\Charset::ISO_8859_1) + { + $oResult = null; + $aEmails = $this->GetFetchEnvelopeValue($iIndex, null); + if (is_array($aEmails) && 0 < count($aEmails)) + { + $oResult = \MailSo\Mime\EmailCollection::NewInstance(); + foreach ($aEmails as $aEmailItem) + { + if (is_array($aEmailItem) && 4 === count($aEmailItem)) + { + $sDisplayName = \MailSo\Base\Utils::DecodeHeaderValue( + self::findEnvelopeIndex($aEmailItem, 0, ''), $sParentCharset); + +// $sRemark = \MailSo\Base\Utils::DecodeHeaderValue( +// self::findEnvelopeIndex($aEmailItem, 1, ''), $sParentCharset); + + $sLocalPart = self::findEnvelopeIndex($aEmailItem, 2, ''); + $sDomainPart = self::findEnvelopeIndex($aEmailItem, 3, ''); + + if (0 < strlen($sLocalPart) && 0 < strlen($sDomainPart)) + { + $oResult->Add( + \MailSo\Mime\Email::NewInstance($sLocalPart.'@'.$sDomainPart, $sDisplayName) + ); + } + } + } + } + + return $oResult; + } + + /** + * @param string $sRfc822SubMimeIndex = '' + * + * @return \MailSo\Imap\BodyStructure|null + */ + public function GetFetchBodyStructure($sRfc822SubMimeIndex = '') + { + $oBodyStructure = null; + $aBodyStructureArray = $this->GetFetchValue(Enumerations\FetchType::BODYSTRUCTURE); + + if (is_array($aBodyStructureArray)) + { + if (0 < strlen($sRfc822SubMimeIndex)) + { + $oBodyStructure = BodyStructure::NewInstanceFromRfc822SubPart($aBodyStructureArray, $sRfc822SubMimeIndex); + } + else + { + $oBodyStructure = BodyStructure::NewInstance($aBodyStructureArray); + } + } + + return $oBodyStructure; + } + + /** + * @param string $sFetchItemName + * + * @return mixed + */ + public function GetFetchValue($sFetchItemName) + { + $mReturn = null; + $bNextIsValue = false; + + if (Enumerations\FetchType::INDEX === $sFetchItemName) + { + $mReturn = $this->oImapResponse->ResponseList[1]; + } + else if (isset($this->oImapResponse->ResponseList[3]) && \is_array($this->oImapResponse->ResponseList[3])) + { + foreach ($this->oImapResponse->ResponseList[3] as $mItem) + { + if ($bNextIsValue) + { + $mReturn = $mItem; + break; + } + + if ($sFetchItemName === $mItem) + { + $bNextIsValue = true; + } + } + } + + return $mReturn; + } + + /** + * @param string $sRfc822SubMimeIndex = '' + * + * @return string + */ + public function GetHeaderFieldsValue($sRfc822SubMimeIndex = '') + { + $sReturn = ''; + $bNextIsValue = false; + + $sRfc822SubMimeIndex = 0 < \strlen($sRfc822SubMimeIndex) ? ''.$sRfc822SubMimeIndex.'.' : ''; + + if (isset($this->oImapResponse->ResponseList[3]) && \is_array($this->oImapResponse->ResponseList[3])) + { + foreach ($this->oImapResponse->ResponseList[3] as $mItem) + { + if ($bNextIsValue) + { + $sReturn = (string) $mItem; + break; + } + + if (\is_string($mItem) && ( + $mItem === 'BODY['.$sRfc822SubMimeIndex.'HEADER]' || + 0 === \strpos($mItem, 'BODY['.$sRfc822SubMimeIndex.'HEADER.FIELDS') || + $mItem === 'BODY['.$sRfc822SubMimeIndex.'MIME]')) + { + $bNextIsValue = true; + } + } + } + + return $sReturn; + } + + private static function findFetchUidAndSize($aList) + { + $bUid = false; + $bSize = false; + if (is_array($aList)) + { + foreach ($aList as $mItem) + { + if (\MailSo\Imap\Enumerations\FetchType::UID === $mItem) + { + $bUid = true; + } + else if (\MailSo\Imap\Enumerations\FetchType::RFC822_SIZE === $mItem) + { + $bSize = true; + } + } + } + + return $bUid && $bSize; + } + + /** + * @param \MailSo\Imap\Response $oImapResponse + * + * @return bool + */ + public static function IsValidFetchImapResponse($oImapResponse) + { + return ( + $oImapResponse + && true !== $oImapResponse->IsStatusResponse + && \MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oImapResponse->ResponseType + && 3 < count($oImapResponse->ResponseList) && 'FETCH' === $oImapResponse->ResponseList[2] + && is_array($oImapResponse->ResponseList[3]) + ); + } + + /** + * @param \MailSo\Imap\Response $oImapResponse + * + * @return bool + */ + public static function IsNotEmptyFetchImapResponse($oImapResponse) + { + return ( + $oImapResponse + && self::IsValidFetchImapResponse($oImapResponse) + && isset($oImapResponse->ResponseList[3]) + && self::findFetchUidAndSize($oImapResponse->ResponseList[3]) + ); + } + + /** + * @param array $aEnvelope + * @param int $iIndex + * @param mixed $mNullResult = null + * + * @return mixed + */ + private static function findEnvelopeIndex($aEnvelope, $iIndex, $mNullResult) + { + return (isset($aEnvelope[$iIndex]) && 'NIL' !== $aEnvelope[$iIndex] && '' !== $aEnvelope[$iIndex]) + ? $aEnvelope[$iIndex] : $mNullResult; + } +} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Imap/Folder.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Imap/Folder.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Imap/Folder.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Imap/Folder.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Imap/FolderInformation.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Imap/FolderInformation.php similarity index 93% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Imap/FolderInformation.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Imap/FolderInformation.php index bc7118d593d49dc2ac2f91ea71c6675d18da1a72..d8fe5a0e2c0f09692202d903f9436447bd6cbe1b 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Imap/FolderInformation.php +++ b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Imap/FolderInformation.php @@ -1,112 +1,112 @@ -FolderName = $sFolderName; - $this->IsWritable = $bIsWritable; - $this->Exists = null; - $this->Recent = null; - $this->Flags = array(); - $this->PermanentFlags = array(); - - $this->Unread = null; - $this->Uidnext = null; - $this->HighestModSeq = null; - } - - /** - * @param string $sFolderName - * @param bool $bIsWritable - * - * @return \MailSo\Imap\FolderInformation - */ - public static function NewInstance($sFolderName, $bIsWritable) - { - return new self($sFolderName, $bIsWritable); - } - - /** - * @param string $sFlag - * - * @return bool - */ - public function IsFlagSupported($sFlag) - { - return \in_array('\\*', $this->PermanentFlags) || - \in_array($sFlag, $this->PermanentFlags) || - \in_array($sFlag, $this->Flags); - } -} +FolderName = $sFolderName; + $this->IsWritable = $bIsWritable; + $this->Exists = null; + $this->Recent = null; + $this->Flags = array(); + $this->PermanentFlags = array(); + + $this->Unread = null; + $this->Uidnext = null; + $this->HighestModSeq = null; + } + + /** + * @param string $sFolderName + * @param bool $bIsWritable + * + * @return \MailSo\Imap\FolderInformation + */ + public static function NewInstance($sFolderName, $bIsWritable) + { + return new self($sFolderName, $bIsWritable); + } + + /** + * @param string $sFlag + * + * @return bool + */ + public function IsFlagSupported($sFlag) + { + return \in_array('\\*', $this->PermanentFlags) || + \in_array($sFlag, $this->PermanentFlags) || + \in_array($sFlag, $this->Flags); + } +} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Imap/ImapClient.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Imap/ImapClient.php similarity index 96% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Imap/ImapClient.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Imap/ImapClient.php index 9e01e2c12df69a01001081872df18ce876ad2f12..19aa9a51e93b0377c0b7dad2cf6e4867ff094a3c 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Imap/ImapClient.php +++ b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Imap/ImapClient.php @@ -1,2667 +1,2667 @@ -iTagCount = 0; - $this->aCapabilityItems = null; - $this->oCurrentFolderInfo = null; - $this->aFetchCallbacks = null; - $this->iResponseBufParsedPos = 0; - - $this->aLastResponse = array(); - $this->bNeedNext = true; - $this->aPartialResponses = array(); - - $this->aTagTimeouts = array(); - - $this->bIsLoggined = false; - $this->bIsSelected = false; - $this->sLogginedUser = ''; - - $this->__FORCE_SELECT_ON_EXAMINE__ = false; - - @\ini_set('xdebug.max_nesting_level', 500); - } - - /** - * @return \MailSo\Imap\ImapClient - */ - public static function NewInstance() - { - return new self(); - } - - /** - * @return string - */ - public function GetLogginedUser() - { - return $this->sLogginedUser; - } - - /** - * @param string $sServerName - * @param int $iPort = 143 - * @param int $iSecurityType = \MailSo\Net\Enumerations\ConnectionSecurityType::AUTO_DETECT - * @param bool $bVerifySsl = false - * @param bool $bAllowSelfSigned = true - * - * @return \MailSo\Imap\ImapClient - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function Connect($sServerName, $iPort = 143, - $iSecurityType = \MailSo\Net\Enumerations\ConnectionSecurityType::AUTO_DETECT, - $bVerifySsl = false, $bAllowSelfSigned = true) - { - $this->aTagTimeouts['*'] = \microtime(true); - - parent::Connect($sServerName, $iPort, $iSecurityType, $bVerifySsl, $bAllowSelfSigned); - - $this->parseResponseWithValidation('*', true); - - if (\MailSo\Net\Enumerations\ConnectionSecurityType::UseStartTLS( - $this->IsSupported('STARTTLS'), $this->iSecurityType)) - { - $this->SendRequestWithCheck('STARTTLS'); - $this->EnableCrypto(); - - $this->aCapabilityItems = null; - } - else if (\MailSo\Net\Enumerations\ConnectionSecurityType::STARTTLS === $this->iSecurityType) - { - $this->writeLogException( - new \MailSo\Net\Exceptions\SocketUnsuppoterdSecureConnectionException('STARTTLS is not supported'), - \MailSo\Log\Enumerations\Type::ERROR, true); - } - - return $this; - } - - protected function _xor($string, $string2) - { - $result = ''; - $size = strlen($string); - for ($i=0; $i<$size; $i++) { - $result .= chr(ord($string[$i]) ^ ord($string2[$i])); - } - return $result; - } - - /** - * @param string $sLogin - * @param string $sPassword - * @param string $sProxyAuthUser = '' - * @param bool $bUseAuthPlainIfSupported = true - * @param bool $bUseAuthCramMd5IfSupported = true - * - * @return \MailSo\Imap\ImapClient - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function Login($sLogin, $sPassword, $sProxyAuthUser = '', - $bUseAuthPlainIfSupported = true, $bUseAuthCramMd5IfSupported = true) - { - if (!\MailSo\Base\Validator::NotEmptyString($sLogin, true) || - !\MailSo\Base\Validator::NotEmptyString($sPassword, true)) - { - $this->writeLogException( - new \MailSo\Base\Exceptions\InvalidArgumentException(), - \MailSo\Log\Enumerations\Type::ERROR, true); - } - - $sLogin = \MailSo\Base\Utils::IdnToAscii(\MailSo\Base\Utils::Trim($sLogin)); - - $sPassword = $sPassword; - - $this->sLogginedUser = $sLogin; - - try - { - if ($bUseAuthCramMd5IfSupported && $this->IsSupported('AUTH=CRAM-MD5')) - { - $this->SendRequest('AUTHENTICATE', array('CRAM-MD5')); - - $aResponse = $this->parseResponseWithValidation(); - if ($aResponse && \is_array($aResponse) && 0 < \count($aResponse) && - \MailSo\Imap\Enumerations\ResponseType::CONTINUATION === $aResponse[\count($aResponse) - 1]->ResponseType) - { - $oContinuationResponse = null; - foreach ($aResponse as $oResponse) - { - if ($oResponse && \MailSo\Imap\Enumerations\ResponseType::CONTINUATION === $oResponse->ResponseType) - { - $oContinuationResponse = $oResponse; - } - } - - if ($oContinuationResponse && !empty($oContinuationResponse->ResponseList[1])) - { - $sTicket = @\base64_decode($oContinuationResponse->ResponseList[1]); - $this->oLogger->Write('ticket: '.$sTicket); - - $sToken = \base64_encode($sLogin.' '.\MailSo\Base\Utils::Hmac($sTicket, $sPassword)); - - if ($this->oLogger) - { - $this->oLogger->AddSecret($sToken); - } - - $this->sendRaw($sToken, true, '*******'); - $this->parseResponseWithValidation(); - } - else - { - $this->writeLogException( - new \MailSo\Imap\Exceptions\LoginException(), - \MailSo\Log\Enumerations\Type::NOTICE, true); - } - } - else - { - $this->writeLogException( - new \MailSo\Imap\Exceptions\LoginException(), - \MailSo\Log\Enumerations\Type::NOTICE, true); - } - } - else if ($bUseAuthPlainIfSupported && $this->IsSupported('AUTH=PLAIN')) - { - $sToken = \base64_encode("\0".$sLogin."\0".$sPassword); - if ($this->oLogger) - { - $this->oLogger->AddSecret($sToken); - } - - if ($this->IsSupported('AUTH=SASL-IR') && false) - { - $this->SendRequestWithCheck('AUTHENTICATE', array('PLAIN', $sToken)); - } - else - { - $this->SendRequest('AUTHENTICATE', array('PLAIN')); - $this->parseResponseWithValidation(); - - $this->sendRaw($sToken, true, '*******'); - $this->parseResponseWithValidation(); - } - } - else - { - if ($this->oLogger) - { - $this->oLogger->AddSecret($this->EscapeString($sPassword)); - } - - $this->SendRequestWithCheck('LOGIN', - array( - $this->EscapeString($sLogin), - $this->EscapeString($sPassword) - )); - } -// else -// { -// $this->writeLogException( -// new \MailSo\Imap\Exceptions\LoginBadMethodException(), -// \MailSo\Log\Enumerations\Type::NOTICE, true); -// } - - if (0 < \strlen($sProxyAuthUser)) - { - $this->SendRequestWithCheck('PROXYAUTH', array($this->EscapeString($sProxyAuthUser))); - } - } - catch (\MailSo\Imap\Exceptions\NegativeResponseException $oException) - { - $this->writeLogException( - new \MailSo\Imap\Exceptions\LoginBadCredentialsException( - $oException->GetResponses(), '', 0, $oException), - \MailSo\Log\Enumerations\Type::NOTICE, true); - } - - $this->bIsLoggined = true; - $this->aCapabilityItems = null; - - return $this; - } - - /** - * @param string $sXOAuth2Token - * - * @return \MailSo\Imap\ImapClient - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function LoginWithXOauth2($sXOAuth2Token) - { - if (!\MailSo\Base\Validator::NotEmptyString($sXOAuth2Token, true)) - { - $this->writeLogException( - new \MailSo\Base\Exceptions\InvalidArgumentException(), - \MailSo\Log\Enumerations\Type::ERROR, true); - } - - if (!$this->IsSupported('AUTH=XOAUTH2')) - { - $this->writeLogException( - new \MailSo\Imap\Exceptions\LoginBadMethodException(), - \MailSo\Log\Enumerations\Type::NOTICE, true); - } - - try - { - $this->SendRequest('AUTHENTICATE', array('XOAUTH2', \trim($sXOAuth2Token))); - $aR = $this->parseResponseWithValidation(); - - if (\is_array($aR) && 0 < \count($aR) && isset($aR[\count($aR) - 1])) - { - $oR = $aR[\count($aR) - 1]; - if (\MailSo\Imap\Enumerations\ResponseType::CONTINUATION === $oR->ResponseType) - { - if (!empty($oR->ResponseList[1]) && preg_match('/^[a-zA-Z0-9=+\/]+$/', $oR->ResponseList[1])) - { - $this->Logger()->Write(\base64_decode($oR->ResponseList[1]), - \MailSo\Log\Enumerations\Type::WARNING); - } - - $this->sendRaw(''); - $this->parseResponseWithValidation(); - } - } - } - catch (\MailSo\Imap\Exceptions\NegativeResponseException $oException) - { - $this->writeLogException( - new \MailSo\Imap\Exceptions\LoginBadCredentialsException( - $oException->GetResponses(), '', 0, $oException), - \MailSo\Log\Enumerations\Type::NOTICE, true); - } - - $this->bIsLoggined = true; - $this->aCapabilityItems = null; - - return $this; - } - - /** - * @return \MailSo\Imap\ImapClient - * - * @throws \MailSo\Net\Exceptions\Exception - */ - public function Logout() - { - if ($this->bIsLoggined) - { - $this->bIsLoggined = false; - $this->SendRequestWithCheck('LOGOUT', array()); - } - - return $this; - } - - /** - * @return \MailSo\Imap\ImapClient - */ - public function ForceCloseConnection() - { - $this->Disconnect(); - - return $this; - } - - /** - * @return bool - */ - public function IsLoggined() - { - return $this->IsConnected() && $this->bIsLoggined; - } - - /** - * @return bool - */ - public function IsSelected() - { - return $this->IsLoggined() && $this->bIsSelected; - } - - /** - * @return array|null - * - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function Capability() - { - $this->SendRequestWithCheck('CAPABILITY', array(), true); - return $this->aCapabilityItems; - } - - /** - * @param string $sExtentionName - * @return bool - * - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function IsSupported($sExtentionName) - { - $bResult = \MailSo\Base\Validator::NotEmptyString($sExtentionName, true); - if ($bResult && null === $this->aCapabilityItems) - { - $this->aCapabilityItems = $this->Capability(); - } - - return $bResult && \is_array($this->aCapabilityItems) && - \in_array(\strtoupper($sExtentionName), $this->aCapabilityItems); - } - - /** - * @return \MailSo\Imap\NamespaceResult|null - * - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function GetNamespace() - { - if (!$this->IsSupported('NAMESPACE')) - { - return null; - } - - $oReturn = false; - - $this->SendRequest('NAMESPACE'); - $aResult = $this->parseResponseWithValidation(); - - $oImapResponse = null; - foreach ($aResult as /* @var $oImapResponse \MailSo\Imap\Response */ $oImapResponse) - { - if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oImapResponse->ResponseType && - 'NAMESPACE' === $oImapResponse->StatusOrIndex) - { - $oReturn = NamespaceResult::NewInstance(); - $oReturn->InitByImapResponse($oImapResponse); - break; - } - } - - if (false === $oReturn) - { - $this->writeLogException( - new \MailSo\Imap\Exceptions\ResponseException(), - \MailSo\Log\Enumerations\Type::ERROR, true); - } - - return $oReturn; - } - - /** - * @return \MailSo\Imap\ImapClient - * - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function Noop() - { - return $this->SendRequestWithCheck('NOOP'); - } - - /** - * @param string $sFolderName - * - * @return \MailSo\Imap\ImapClient - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function FolderCreate($sFolderName) - { - return $this->SendRequestWithCheck('CREATE', - array($this->EscapeString($sFolderName))); - } - - /** - * @param string $sFolderName - * - * @return \MailSo\Imap\ImapClient - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function FolderDelete($sFolderName) - { - return $this->SendRequestWithCheck('DELETE', - array($this->EscapeString($sFolderName))); - } - - /** - * @param string $sFolderName - * - * @return \MailSo\Imap\ImapClient - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function FolderSubscribe($sFolderName) - { - return $this->SendRequestWithCheck('SUBSCRIBE', - array($this->EscapeString($sFolderName))); - } - - /** - * @param string $sFolderName - * - * @return \MailSo\Imap\ImapClient - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function FolderUnSubscribe($sFolderName) - { - return $this->SendRequestWithCheck('UNSUBSCRIBE', - array($this->EscapeString($sFolderName))); - } - - /** - * @param string $sOldFolderName - * @param string $sNewFolderName - * - * @return \MailSo\Imap\ImapClient - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function FolderRename($sOldFolderName, $sNewFolderName) - { - return $this->SendRequestWithCheck('RENAME', array( - $this->EscapeString($sOldFolderName), - $this->EscapeString($sNewFolderName))); - } - - /** - * @param array $aResult - * - * @return array - */ - protected function getStatusFolderInformation($aResult) - { - $aReturn = array(); - - if (\is_array($aResult)) - { - $oImapResponse = null; - foreach ($aResult as /* @var $oImapResponse \MailSo\Imap\Response */ $oImapResponse) - { - if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oImapResponse->ResponseType && - 'STATUS' === $oImapResponse->StatusOrIndex && isset($oImapResponse->ResponseList[3]) && - \is_array($oImapResponse->ResponseList[3])) - { - $sName = null; - foreach ($oImapResponse->ResponseList[3] as $sArrayItem) - { - if (null === $sName) - { - $sName = $sArrayItem; - } - else - { - $aReturn[$sName] = $sArrayItem; - $sName = null; - } - } - } - } - } - - return $aReturn; - } - - /** - * @param string $sFolderName - * @param array $aStatusItems - * - * @return array|bool - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function FolderStatus($sFolderName, array $aStatusItems) - { - $aResult = false; - if (\count($aStatusItems) > 0) - { - $this->SendRequest('STATUS', - array($this->EscapeString($sFolderName), $aStatusItems)); - - $aResult = $this->getStatusFolderInformation( - $this->parseResponseWithValidation()); - } - - return $aResult; - } - - /** - * @param array $aResult - * @param string $sStatus - * @param bool $bUseListStatus = false - * - * @return array - */ - private function getFoldersFromResult(array $aResult, $sStatus, $bUseListStatus = false) - { - $aReturn = array(); - - $sDelimiter = ''; - $bInbox = false; - - $oImapResponse = null; - foreach ($aResult as /* @var $oImapResponse \MailSo\Imap\Response */ $oImapResponse) - { - if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oImapResponse->ResponseType && - $sStatus === $oImapResponse->StatusOrIndex && 5 === count($oImapResponse->ResponseList)) - { - try - { - $oFolder = Folder::NewInstance($oImapResponse->ResponseList[4], - $oImapResponse->ResponseList[3], $oImapResponse->ResponseList[2]); - - if ($oFolder->IsInbox()) - { - $bInbox = true; - } - - if (empty($sDelimiter)) - { - $sDelimiter = $oFolder->Delimiter(); - } - - $aReturn[] = $oFolder; - } - catch (\MailSo\Base\Exceptions\InvalidArgumentException $oException) - { - $this->writeLogException($oException, \MailSo\Log\Enumerations\Type::WARNING, false); - } - } - } - - if (!$bInbox && !empty($sDelimiter)) - { - $aReturn[] = Folder::NewInstance('INBOX', $sDelimiter); - } - - if ($bUseListStatus) - { - foreach ($aResult as /* @var $oImapResponse \MailSo\Imap\Response */ $oImapResponse) - { - if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oImapResponse->ResponseType && - 'STATUS' === $oImapResponse->StatusOrIndex && - isset($oImapResponse->ResponseList[2]) && - isset($oImapResponse->ResponseList[3]) && - \is_array($oImapResponse->ResponseList[3])) - { - $sFolderNameRaw = $oImapResponse->ResponseList[2]; - - $oCurrentFolder = null; - foreach ($aReturn as &$oFolder) - { - if ($oFolder && $sFolderNameRaw === $oFolder->FullNameRaw()) - { - $oCurrentFolder =& $oFolder; - break; - } - } - - if (null !== $oCurrentFolder) - { - $sName = null; - $aStatus = array(); - - foreach ($oImapResponse->ResponseList[3] as $sArrayItem) - { - if (null === $sName) - { - $sName = $sArrayItem; - } - else - { - $aStatus[$sName] = $sArrayItem; - $sName = null; - } - } - - if (0 < count($aStatus)) - { - $oCurrentFolder->SetExtended('STATUS', $aStatus); - } - } - - unset($oCurrentFolder); - } - } - } - - return $aReturn; - } - - /** - * @param bool $bIsSubscribeList - * @param string $sParentFolderName = '' - * @param string $sListPattern = '*' - * @param bool $bUseListStatus = false - * - * @return array - * - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - private function specificFolderList($bIsSubscribeList, $sParentFolderName = '', $sListPattern = '*', $bUseListStatus = false) - { - $sCmd = 'LSUB'; - if (!$bIsSubscribeList) - { - $sCmd = 'LIST'; - } - - $sListPattern = 0 === strlen(trim($sListPattern)) ? '*' : $sListPattern; - - $aParameters = array( - $this->EscapeString($sParentFolderName), - $this->EscapeString($sListPattern) - ); - - if ($bUseListStatus && !$bIsSubscribeList && $this->IsSupported('LIST-STATUS')) - { - $aL = array( - \MailSo\Imap\Enumerations\FolderStatus::MESSAGES, - \MailSo\Imap\Enumerations\FolderStatus::UNSEEN, - \MailSo\Imap\Enumerations\FolderStatus::UIDNEXT - ); - -// if ($this->IsSupported('CONDSTORE')) -// { -// $aL[] = \MailSo\Imap\Enumerations\FolderStatus::HIGHESTMODSEQ; -// } - - $aParameters[] = 'RETURN'; - $aParameters[] = array('STATUS', $aL); - } - else - { - $bUseListStatus = false; - } - - $this->SendRequest($sCmd, $aParameters); - - return $this->getFoldersFromResult( - $this->parseResponseWithValidation(), $sCmd, $bUseListStatus); - } - - /** - * @param string $sParentFolderName = '' - * @param string $sListPattern = '*' - * - * @return array - * - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function FolderList($sParentFolderName = '', $sListPattern = '*') - { - return $this->specificFolderList(false, $sParentFolderName, $sListPattern); - } - - /** - * @param string $sParentFolderName = '' - * @param string $sListPattern = '*' - * - * @return array - * - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function FolderSubscribeList($sParentFolderName = '', $sListPattern = '*') - { - return $this->specificFolderList(true, $sParentFolderName, $sListPattern); - } - - /** - * @param string $sParentFolderName = '' - * @param string $sListPattern = '*' - * - * @return array - * - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function FolderStatusList($sParentFolderName = '', $sListPattern = '*') - { - return $this->specificFolderList(false, $sParentFolderName, $sListPattern, true); - } - - /** - * @param array $aResult - * @param string $sFolderName - * @param bool $bIsWritable - * - * @return void - */ - protected function initCurrentFolderInformation($aResult, $sFolderName, $bIsWritable) - { - if (\is_array($aResult)) - { - $oImapResponse = null; - $oResult = FolderInformation::NewInstance($sFolderName, $bIsWritable); - - foreach ($aResult as /* @var $oImapResponse \MailSo\Imap\Response */ $oImapResponse) - { - if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oImapResponse->ResponseType) - { - if (\count($oImapResponse->ResponseList) > 2 && - 'FLAGS' === $oImapResponse->ResponseList[1] && \is_array($oImapResponse->ResponseList[2])) - { - $oResult->Flags = $oImapResponse->ResponseList[2]; - } - - if (is_array($oImapResponse->OptionalResponse) && \count($oImapResponse->OptionalResponse) > 1) - { - if ('PERMANENTFLAGS' === $oImapResponse->OptionalResponse[0] && - is_array($oImapResponse->OptionalResponse[1])) - { - $oResult->PermanentFlags = $oImapResponse->OptionalResponse[1]; - } - else if ('UIDVALIDITY' === $oImapResponse->OptionalResponse[0] && - isset($oImapResponse->OptionalResponse[1])) - { - $oResult->Uidvalidity = $oImapResponse->OptionalResponse[1]; - } - else if ('UNSEEN' === $oImapResponse->OptionalResponse[0] && - isset($oImapResponse->OptionalResponse[1]) && - is_numeric($oImapResponse->OptionalResponse[1])) - { - $oResult->Unread = (int) $oImapResponse->OptionalResponse[1]; - } - else if ('UIDNEXT' === $oImapResponse->OptionalResponse[0] && - isset($oImapResponse->OptionalResponse[1])) - { - $oResult->Uidnext = $oImapResponse->OptionalResponse[1]; - } - else if ('HIGHESTMODSEQ' === $oImapResponse->OptionalResponse[0] && - isset($oImapResponse->OptionalResponse[1]) && - \is_numeric($oImapResponse->OptionalResponse[1])) - { - $oResult->HighestModSeq = \trim($oImapResponse->OptionalResponse[1]); - } - } - - if (\count($oImapResponse->ResponseList) > 2 && - \is_string($oImapResponse->ResponseList[2]) && - \is_numeric($oImapResponse->ResponseList[1])) - { - switch($oImapResponse->ResponseList[2]) - { - case 'EXISTS': - $oResult->Exists = (int) $oImapResponse->ResponseList[1]; - break; - case 'RECENT': - $oResult->Recent = (int) $oImapResponse->ResponseList[1]; - break; - } - } - } - } - - $this->oCurrentFolderInfo = $oResult; - } - } - - /** - * @param string $sFolderName - * @param bool $bIsWritable - * @param bool $bReSelectSameFolders - * - * @return \MailSo\Imap\ImapClient - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - protected function selectOrExamineFolder($sFolderName, $bIsWritable, $bReSelectSameFolders) - { - if (!$bReSelectSameFolders) - { - if ($this->oCurrentFolderInfo && - $sFolderName === $this->oCurrentFolderInfo->FolderName && - $bIsWritable === $this->oCurrentFolderInfo->IsWritable) - { - return $this; - } - } - - if (!\MailSo\Base\Validator::NotEmptyString($sFolderName, true)) - { - throw new \MailSo\Base\Exceptions\InvalidArgumentException(); - } - - $this->SendRequest(($bIsWritable) ? 'SELECT' : 'EXAMINE', - array($this->EscapeString($sFolderName))); - - $this->initCurrentFolderInformation( - $this->parseResponseWithValidation(), $sFolderName, $bIsWritable); - - $this->bIsSelected = true; - - return $this; - } - - /** - * @param string $sFolderName - * @param bool $bReSelectSameFolders = false - * - * @return \MailSo\Imap\ImapClient - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function FolderSelect($sFolderName, $bReSelectSameFolders = false) - { - return $this->selectOrExamineFolder($sFolderName, true, $bReSelectSameFolders); - } - - /** - * @param string $sFolderName - * @param bool $bReSelectSameFolders = false - * - * @return \MailSo\Imap\ImapClient - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function FolderExamine($sFolderName, $bReSelectSameFolders = false) - { - return $this->selectOrExamineFolder($sFolderName, $this->__FORCE_SELECT_ON_EXAMINE__, $bReSelectSameFolders); - } - - /** - * @return \MailSo\Imap\ImapClient - * - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function FolderUnSelect() - { - if ($this->IsSelected() && $this->IsSupported('UNSELECT')) - { - $this->SendRequestWithCheck('UNSELECT'); - $this->bIsSelected = false; - } - - return $this; - } - - /** - * @param array $aInputFetchItems - * @param string $sIndexRange - * @param bool $bIndexIsUid - * - * @return array - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function Fetch(array $aInputFetchItems, $sIndexRange, $bIndexIsUid) - { - $sIndexRange = (string) $sIndexRange; - if (!\MailSo\Base\Validator::NotEmptyString($sIndexRange, true)) - { - $this->writeLogException( - new \MailSo\Base\Exceptions\InvalidArgumentException(), - \MailSo\Log\Enumerations\Type::ERROR, true); - } - - $aFetchItems = \MailSo\Imap\Enumerations\FetchType::ChangeFetchItemsBefourRequest($aInputFetchItems); - foreach ($aFetchItems as $sName => $mItem) - { - if (0 < \strlen($sName) && '' !== $mItem) - { - if (null === $this->aFetchCallbacks) - { - $this->aFetchCallbacks = array(); - } - - $this->aFetchCallbacks[$sName] = $mItem; - } - } - - $this->SendRequest((($bIndexIsUid) ? 'UID ' : '').'FETCH', array($sIndexRange, \array_keys($aFetchItems))); - $aResult = $this->validateResponse($this->parseResponse()); - $this->aFetchCallbacks = null; - - $aReturn = array(); - $oImapResponse = null; - foreach ($aResult as $oImapResponse) - { - if (FetchResponse::IsValidFetchImapResponse($oImapResponse)) - { - if (FetchResponse::IsNotEmptyFetchImapResponse($oImapResponse)) - { - $aReturn[] = FetchResponse::NewInstance($oImapResponse); - } - else - { - if ($this->oLogger) - { - $this->oLogger->Write('Skipped Imap Response! ['.$oImapResponse->ToLine().']', \MailSo\Log\Enumerations\Type::NOTICE); - } - } - } - } - - return $aReturn; - } - - - /** - * @return array|false - * - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function Quota() - { - $aReturn = false; - if ($this->IsSupported('QUOTA')) - { - $this->SendRequest('GETQUOTAROOT "INBOX"'); - $aResult = $this->parseResponseWithValidation(); - - $aReturn = array(0, 0); - $oImapResponse = null; - foreach ($aResult as /* @var $oImapResponse \MailSo\Imap\Response */ $oImapResponse) - { - if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oImapResponse->ResponseType - && 'QUOTA' === $oImapResponse->StatusOrIndex - && \is_array($oImapResponse->ResponseList) - && isset($oImapResponse->ResponseList[3]) - && \is_array($oImapResponse->ResponseList[3]) - && 2 < \count($oImapResponse->ResponseList[3]) - && 'STORAGE' === \strtoupper($oImapResponse->ResponseList[3][0]) - && \is_numeric($oImapResponse->ResponseList[3][1]) - && \is_numeric($oImapResponse->ResponseList[3][2]) - ) - { - $aReturn = array( - (int) $oImapResponse->ResponseList[3][1], - (int) $oImapResponse->ResponseList[3][2], - 0, - 0 - ); - - if (5 < \count($oImapResponse->ResponseList[3]) - && 'MESSAGE' === \strtoupper($oImapResponse->ResponseList[3][3]) - && \is_numeric($oImapResponse->ResponseList[3][4]) - && \is_numeric($oImapResponse->ResponseList[3][5]) - ) - { - $aReturn[2] = (int) $oImapResponse->ResponseList[3][4]; - $aReturn[3] = (int) $oImapResponse->ResponseList[3][5]; - } - } - } - } - - return $aReturn; - } - - /** - * @param array $aSortTypes - * @param string $sSearchCriterias - * @param bool $bReturnUid - * - * @return array - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function MessageSimpleSort($aSortTypes, $sSearchCriterias = 'ALL', $bReturnUid = true) - { - $sCommandPrefix = ($bReturnUid) ? 'UID ' : ''; - $sSearchCriterias = !\MailSo\Base\Validator::NotEmptyString($sSearchCriterias, true) || '*' === $sSearchCriterias - ? 'ALL' : $sSearchCriterias; - - if (!\is_array($aSortTypes) || 0 === \count($aSortTypes)) - { - $this->writeLogException( - new \MailSo\Base\Exceptions\InvalidArgumentException(), - \MailSo\Log\Enumerations\Type::ERROR, true); - } - else if (!$this->IsSupported('SORT')) - { - $this->writeLogException( - new \MailSo\Base\Exceptions\InvalidArgumentException(), - \MailSo\Log\Enumerations\Type::ERROR, true); - } - - $aRequest = array(); - $aRequest[] = $aSortTypes; - $aRequest[] = \MailSo\Base\Utils::IsAscii($sSearchCriterias) ? 'US-ASCII' : 'UTF-8'; - $aRequest[] = $sSearchCriterias; - - $sCmd = 'SORT'; - - $this->SendRequest($sCommandPrefix.$sCmd, $aRequest); - $aResult = $this->parseResponseWithValidation(); - - $aReturn = array(); - $oImapResponse = null; - foreach ($aResult as /* @var $oImapResponse \MailSo\Imap\Response */ $oImapResponse) - { - if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oImapResponse->ResponseType - && ($sCmd === $oImapResponse->StatusOrIndex || - ($bReturnUid && 'UID' === $oImapResponse->StatusOrIndex) && !empty($oImapResponse->ResponseList[2]) && - $sCmd === $oImapResponse->ResponseList[2]) - && \is_array($oImapResponse->ResponseList) - && 2 < \count($oImapResponse->ResponseList)) - { - $iStart = 2; - if ($bReturnUid && 'UID' === $oImapResponse->StatusOrIndex && - !empty($oImapResponse->ResponseList[2]) && - $sCmd === $oImapResponse->ResponseList[2]) - { - $iStart = 3; - } - - for ($iIndex = $iStart, $iLen = \count($oImapResponse->ResponseList); $iIndex < $iLen; $iIndex++) - { - $aReturn[] = (int) $oImapResponse->ResponseList[$iIndex]; - } - } - } - - return $aReturn; - } - - /** - * @param bool $bSort = false - * @param string $sSearchCriterias = 'ALL' - * @param array $aSearchOrSortReturn = null - * @param bool $bReturnUid = true - * @param string $sLimit = '' - * @param string $sCharset = '' - * @param array $aSortTypes = null - * - * @return array - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - private function simpleESearchOrESortHelper($bSort = false, $sSearchCriterias = 'ALL', $aSearchOrSortReturn = null, $bReturnUid = true, $sLimit = '', $sCharset = '', $aSortTypes = null) - { - $sCommandPrefix = ($bReturnUid) ? 'UID ' : ''; - $sSearchCriterias = 0 === \strlen($sSearchCriterias) || '*' === $sSearchCriterias - ? 'ALL' : $sSearchCriterias; - - $sCmd = $bSort ? 'SORT': 'SEARCH'; - if ($bSort && (!\is_array($aSortTypes) || 0 === \count($aSortTypes) || !$this->IsSupported('SORT'))) - { - $this->writeLogException( - new \MailSo\Base\Exceptions\InvalidArgumentException(), - \MailSo\Log\Enumerations\Type::ERROR, true); - } - - if (!$this->IsSupported($bSort ? 'ESORT' : 'ESEARCH')) - { - $this->writeLogException( - new \MailSo\Base\Exceptions\InvalidArgumentException(), - \MailSo\Log\Enumerations\Type::ERROR, true); - } - - if (!\is_array($aSearchOrSortReturn) || 0 === \count($aSearchOrSortReturn)) - { - $aSearchOrSortReturn = array('ALL'); - } - - $aRequest = array(); - if ($bSort) - { - $aRequest[] = 'RETURN'; - $aRequest[] = $aSearchOrSortReturn; - - $aRequest[] = $aSortTypes; - $aRequest[] = \MailSo\Base\Utils::IsAscii($sSearchCriterias) ? 'US-ASCII' : 'UTF-8'; - } - else - { - if (0 < \strlen($sCharset)) - { - $aRequest[] = 'CHARSET'; - $aRequest[] = \strtoupper($sCharset); - } - - $aRequest[] = 'RETURN'; - $aRequest[] = $aSearchOrSortReturn; - } - - $aRequest[] = $sSearchCriterias; - - if (0 < \strlen($sLimit)) - { - $aRequest[] = $sLimit; - } - - $this->SendRequest($sCommandPrefix.$sCmd, $aRequest); - $sRequestTag = $this->getCurrentTag(); - - $aResult = array(); - $aResponse = $this->parseResponseWithValidation(); - - if (\is_array($aResponse)) - { - $oImapResponse = null; - foreach ($aResponse as /* @var $oImapResponse \MailSo\Imap\Response */ $oImapResponse) - { - if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oImapResponse->ResponseType - && ('ESEARCH' === $oImapResponse->StatusOrIndex || 'ESORT' === $oImapResponse->StatusOrIndex) - && \is_array($oImapResponse->ResponseList) - && isset($oImapResponse->ResponseList[2], $oImapResponse->ResponseList[2][0], $oImapResponse->ResponseList[2][1]) - && 'TAG' === $oImapResponse->ResponseList[2][0] && $sRequestTag === $oImapResponse->ResponseList[2][1] - && (!$bReturnUid || ($bReturnUid && !empty($oImapResponse->ResponseList[3]) && 'UID' === $oImapResponse->ResponseList[3])) - ) - { - $iStart = 3; - foreach ($oImapResponse->ResponseList as $iIndex => $mItem) - { - if ($iIndex >= $iStart) - { - switch ($mItem) - { - case 'ALL': - case 'MAX': - case 'MIN': - case 'COUNT': - if (isset($oImapResponse->ResponseList[$iIndex + 1])) - { - $aResult[$mItem] = $oImapResponse->ResponseList[$iIndex + 1]; - } - break; - } - } - } - } - } - } - - return $aResult; - } - - /** - * @param string $sSearchCriterias = 'ALL' - * @param array $aSearchReturn = null - * @param bool $bReturnUid = true - * @param string $sLimit = '' - * @param string $sCharset = '' - * - * @return array - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function MessageSimpleESearch($sSearchCriterias = 'ALL', $aSearchReturn = null, $bReturnUid = true, $sLimit = '', $sCharset = '') - { - return $this->simpleESearchOrESortHelper(false, $sSearchCriterias, $aSearchReturn, $bReturnUid, $sLimit, $sCharset); - } - - /** - * @param array $aSortTypes - * @param string $sSearchCriterias = 'ALL' - * @param array $aSearchReturn = null - * @param bool $bReturnUid = true - * @param string $sLimit = '' - * - * @return array - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function MessageSimpleESort($aSortTypes, $sSearchCriterias = 'ALL', $aSearchReturn = null, $bReturnUid = true, $sLimit = '') - { - return $this->simpleESearchOrESortHelper(true, $sSearchCriterias, $aSearchReturn, $bReturnUid, $sLimit, '', $aSortTypes); - } - - /** - * @param array $aResult - * @return \MailSo\Imap\Response - */ - private function findLastResponse($aResult) - { - $oResult = null; - if (\is_array($aResult) && 0 < \count($aResult)) - { - $oResult = $aResult[\count($aResult) - 1]; - if (!($oResult instanceof \MailSo\Imap\Response)) - { - $oResult = null; - } - } - - return $oResult; - } - - /** - * @param string $sSearchCriterias - * @param bool $bReturnUid = true - * @param string $sCharset = '' - * - * @return array - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function MessageSimpleSearch($sSearchCriterias = 'ALL', $bReturnUid = true, $sCharset = '') - { - $sCommandPrefix = ($bReturnUid) ? 'UID ' : ''; - $sSearchCriterias = 0 === \strlen($sSearchCriterias) || '*' === $sSearchCriterias - ? 'ALL' : $sSearchCriterias; - - $aRequest = array(); - if (0 < \strlen($sCharset)) - { - $aRequest[] = 'CHARSET'; - $aRequest[] = \strtoupper($sCharset); - } - - $aRequest[] = $sSearchCriterias; - - $sCmd = 'SEARCH'; - - $sCont = $this->SendRequest($sCommandPrefix.$sCmd, $aRequest, true); - if ('' !== $sCont) - { - $aResult = $this->parseResponseWithValidation(); - $oItem = $this->findLastResponse($aResult); - - if ($oItem && \MailSo\Imap\Enumerations\ResponseType::CONTINUATION === $oItem->ResponseType) - { - $aParts = explode("\r\n", $sCont); - foreach ($aParts as $sLine) - { - $this->sendRaw($sLine); - - $aResult = $this->parseResponseWithValidation(); - $oItem = $this->findLastResponse($aResult); - if ($oItem && \MailSo\Imap\Enumerations\ResponseType::CONTINUATION === $oItem->ResponseType) - { - continue; - } - } - } - } - else - { - $aResult = $this->parseResponseWithValidation(); - } - - $aReturn = array(); - $oImapResponse = null; - foreach ($aResult as /* @var $oImapResponse \MailSo\Imap\Response */ $oImapResponse) - { - if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oImapResponse->ResponseType - && ($sCmd === $oImapResponse->StatusOrIndex || - ($bReturnUid && 'UID' === $oImapResponse->StatusOrIndex) && !empty($oImapResponse->ResponseList[2]) && - $sCmd === $oImapResponse->ResponseList[2]) - && \is_array($oImapResponse->ResponseList) - && 2 < count($oImapResponse->ResponseList)) - { - $iStart = 2; - if ($bReturnUid && 'UID' === $oImapResponse->StatusOrIndex && - !empty($oImapResponse->ResponseList[2]) && - $sCmd === $oImapResponse->ResponseList[2]) - { - $iStart = 3; - } - - for ($iIndex = $iStart, $iLen = \count($oImapResponse->ResponseList); $iIndex < $iLen; $iIndex++) - { - $aReturn[] = (int) $oImapResponse->ResponseList[$iIndex]; - } - } - } - - $aReturn = \array_reverse($aReturn); - return $aReturn; - } - - /** - * @param mixed $aValue - * - * @return mixed - */ - private function validateThreadItem($aValue) - { - $mResult = false; - if (\is_numeric($aValue)) - { - $mResult = (int) $aValue; - if (0 >= $mResult) - { - $mResult = false; - } - } - else if (\is_array($aValue)) - { - if (1 === \count($aValue) && \is_numeric($aValue[0])) - { - $mResult = (int) $aValue[0]; - if (0 >= $mResult) - { - $mResult = false; - } - } - else - { - $mResult = array(); - foreach ($aValue as $aValueItem) - { - $mTemp = $this->validateThreadItem($aValueItem); - if (false !== $mTemp) - { - $mResult[] = $mTemp; - } - } - } - } - - return $mResult; - } - - /** - * @param string $sSearchCriterias = 'ALL' - * @param bool $bReturnUid = true - * @param string $sCharset = \MailSo\Base\Enumerations\Charset::UTF_8 - * - * @return array - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function MessageSimpleThread($sSearchCriterias = 'ALL', $bReturnUid = true, $sCharset = \MailSo\Base\Enumerations\Charset::UTF_8) - { - $sCommandPrefix = ($bReturnUid) ? 'UID ' : ''; - $sSearchCriterias = !\MailSo\Base\Validator::NotEmptyString($sSearchCriterias, true) || '*' === $sSearchCriterias - ? 'ALL' : $sSearchCriterias; - - $sThreadType = ''; - switch (true) - { - case $this->IsSupported('THREAD=REFS'): - $sThreadType = 'REFS'; - break; - case $this->IsSupported('THREAD=REFERENCES'): - $sThreadType = 'REFERENCES'; - break; - case $this->IsSupported('THREAD=ORDEREDSUBJECT'): - $sThreadType = 'ORDEREDSUBJECT'; - break; - default: - $this->writeLogException( - new Exceptions\RuntimeException('Thread is not supported'), - \MailSo\Log\Enumerations\Type::ERROR, true); - break; - } - - $aRequest = array(); - $aRequest[] = $sThreadType; - $aRequest[] = \strtoupper($sCharset); - $aRequest[] = $sSearchCriterias; - - $sCmd = 'THREAD'; - - $this->SendRequest($sCommandPrefix.$sCmd, $aRequest); - $aResult = $this->parseResponseWithValidation(); - - $aReturn = array(); - $oImapResponse = null; - - foreach ($aResult as /* @var $oImapResponse \MailSo\Imap\Response */ $oImapResponse) - { - if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oImapResponse->ResponseType - && ($sCmd === $oImapResponse->StatusOrIndex || - ($bReturnUid && 'UID' === $oImapResponse->StatusOrIndex) && !empty($oImapResponse->ResponseList[2]) && - $sCmd === $oImapResponse->ResponseList[2]) - && \is_array($oImapResponse->ResponseList) - && 2 < \count($oImapResponse->ResponseList)) - { - $iStart = 2; - if ($bReturnUid && 'UID' === $oImapResponse->StatusOrIndex && - !empty($oImapResponse->ResponseList[2]) && - $sCmd === $oImapResponse->ResponseList[2]) - { - $iStart = 3; - } - - for ($iIndex = $iStart, $iLen = \count($oImapResponse->ResponseList); $iIndex < $iLen; $iIndex++) - { - $aNewValue = $this->validateThreadItem($oImapResponse->ResponseList[$iIndex]); - if (false !== $aNewValue) - { - $aReturn[] = $aNewValue; - } - } - } - } - - return $aReturn; - } - - /** - * @param string $sToFolder - * @param string $sIndexRange - * @param bool $bIndexIsUid - * - * @return \MailSo\Imap\ImapClient - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function MessageCopy($sToFolder, $sIndexRange, $bIndexIsUid) - { - if (0 === \strlen($sIndexRange)) - { - $this->writeLogException( - new \MailSo\Base\Exceptions\InvalidArgumentException(), - \MailSo\Log\Enumerations\Type::ERROR, true); - } - - $sCommandPrefix = ($bIndexIsUid) ? 'UID ' : ''; - return $this->SendRequestWithCheck($sCommandPrefix.'COPY', - array($sIndexRange, $this->EscapeString($sToFolder))); - } - - /** - * @param string $sToFolder - * @param string $sIndexRange - * @param bool $bIndexIsUid - * - * @return \MailSo\Imap\ImapClient - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function MessageMove($sToFolder, $sIndexRange, $bIndexIsUid) - { - if (0 === \strlen($sIndexRange)) - { - $this->writeLogException( - new \MailSo\Base\Exceptions\InvalidArgumentException(), - \MailSo\Log\Enumerations\Type::ERROR, true); - } - - if (!$this->IsSupported('MOVE')) - { - $this->writeLogException( - new Exceptions\RuntimeException('Move is not supported'), - \MailSo\Log\Enumerations\Type::ERROR, true); - } - - $sCommandPrefix = ($bIndexIsUid) ? 'UID ' : ''; - return $this->SendRequestWithCheck($sCommandPrefix.'MOVE', - array($sIndexRange, $this->EscapeString($sToFolder))); - } - - /** - * @param string $sUidRangeIfSupported = '' - * @param bool $bForceUidExpunge = false - * @param bool $bExpungeAll = false - * - * @return \MailSo\Imap\ImapClient - * - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function MessageExpunge($sUidRangeIfSupported = '', $bForceUidExpunge = false, $bExpungeAll = false) - { - $sUidRangeIfSupported = \trim($sUidRangeIfSupported); - - $sCmd = 'EXPUNGE'; - $aArguments = array(); - - if (!$bExpungeAll && $bForceUidExpunge && 0 < \strlen($sUidRangeIfSupported) && $this->IsSupported('UIDPLUS')) - { - $sCmd = 'UID '.$sCmd; - $aArguments = array($sUidRangeIfSupported); - } - - return $this->SendRequestWithCheck($sCmd, $aArguments); - } - - /** - * @param string $sIndexRange - * @param bool $bIndexIsUid - * @param array $aInputStoreItems - * @param string $sStoreAction - * - * @return \MailSo\Imap\ImapClient - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function MessageStoreFlag($sIndexRange, $bIndexIsUid, $aInputStoreItems, $sStoreAction) - { - if (!\MailSo\Base\Validator::NotEmptyString($sIndexRange, true) || - !\MailSo\Base\Validator::NotEmptyString($sStoreAction, true) || - 0 === \count($aInputStoreItems)) - { - return false; - } - - $sCmd = ($bIndexIsUid) ? 'UID STORE' : 'STORE'; - return $this->SendRequestWithCheck($sCmd, array($sIndexRange, $sStoreAction, $aInputStoreItems)); - } - - /** - * @param string $sFolderName - * @param resource $rMessageAppendStream - * @param int $iStreamSize - * @param array $aAppendFlags = null - * @param int $iUid = null - * @param int $sDateTime = 0 - * - * @return \MailSo\Imap\ImapClient - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function MessageAppendStream($sFolderName, $rMessageAppendStream, $iStreamSize, $aAppendFlags = null, &$iUid = null, $sDateTime = 0) - { - $aData = array($this->EscapeString($sFolderName), $aAppendFlags); - if (0 < $sDateTime) - { - $aData[] = $this->EscapeString(\gmdate('d-M-Y H:i:s', $sDateTime).' +0000'); - } - - $aData[] = '{'.$iStreamSize.'}'; - - $this->SendRequest('APPEND', $aData); - $this->parseResponseWithValidation(); - - $this->writeLog('Write to connection stream', \MailSo\Log\Enumerations\Type::NOTE); - - \MailSo\Base\Utils::MultipleStreamWriter($rMessageAppendStream, array($this->rConnect)); - - $this->sendRaw(''); - $this->parseResponseWithValidation(); - - if (null !== $iUid) - { - $aLastResponse = $this->GetLastResponse(); - if (\is_array($aLastResponse) && 0 < \count($aLastResponse) && $aLastResponse[\count($aLastResponse) - 1]) - { - $oLast = $aLastResponse[count($aLastResponse) - 1]; - if ($oLast && \MailSo\Imap\Enumerations\ResponseType::TAGGED === $oLast->ResponseType && \is_array($oLast->OptionalResponse)) - { - if (0 < \strlen($oLast->OptionalResponse[0]) && - 0 < \strlen($oLast->OptionalResponse[2]) && - 'APPENDUID' === strtoupper($oLast->OptionalResponse[0]) && - \is_numeric($oLast->OptionalResponse[2]) - ) - { - $iUid = (int) $oLast->OptionalResponse[2]; - } - } - } - } - - return $this; - } - - /** - * @return \MailSo\Imap\FolderInformation - */ - public function FolderCurrentInformation() - { - return $this->oCurrentFolderInfo; - } - - /** - * @param string $sCommand - * @param array $aParams = array() - * @param bool $bBreakOnLiteral = false - * - * @return string - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - */ - public function SendRequest($sCommand, $aParams = array(), $bBreakOnLiteral = false) - { - if (!\MailSo\Base\Validator::NotEmptyString($sCommand, true) || !\is_array($aParams)) - { - $this->writeLogException( - new \MailSo\Base\Exceptions\InvalidArgumentException(), - \MailSo\Log\Enumerations\Type::ERROR, true); - } - - $this->IsConnected(true); - - $sTag = $this->getNewTag(); - - $sCommand = \trim($sCommand); - $sRealCommand = $sTag.' '.$sCommand.$this->prepearParamLine($aParams); - - $sFakeCommand = ''; - $aFakeParams = $this->secureRequestParams($sCommand, $aParams); - if (null !== $aFakeParams) - { - $sFakeCommand = $sTag.' '.$sCommand.$this->prepearParamLine($aFakeParams); - } - - $this->aTagTimeouts[$sTag] = \microtime(true); - - if ($bBreakOnLiteral && !\preg_match('/\d\+\}\r\n/', $sRealCommand)) - { - $iPos = \strpos($sRealCommand, "}\r\n"); - if (false !== $iPos) - { - $iFakePos = \strpos($sFakeCommand, "}\r\n"); - - $this->sendRaw(\substr($sRealCommand, 0, $iPos + 1), true, - false !== $iFakePos ? \substr($sFakeCommand, 0, $iFakePos + 3) : ''); - - return \substr($sRealCommand, $iPos + 3); - } - } - - $this->sendRaw($sRealCommand, true, $sFakeCommand); - return ''; - } - - /** - * @param string $sCommand - * @param array $aParams - * - * @return array|null - */ - private function secureRequestParams($sCommand, $aParams) - { - $aResult = null; - switch ($sCommand) - { - case 'LOGIN': - $aResult = $aParams; - if (\is_array($aResult) && 2 === count($aResult)) - { - $aResult[1] = '"********"'; - } - break; - } - - return $aResult; - } - - /** - * @param string $sCommand - * @param array $aParams = array() - * @param bool $bFindCapa = false - * - * @return \MailSo\Imap\ImapClient - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function SendRequestWithCheck($sCommand, $aParams = array(), $bFindCapa = false) - { - $this->SendRequest($sCommand, $aParams); - $this->parseResponseWithValidation(null, $bFindCapa); - - return $this; - } - - /** - * @return array - */ - public function GetLastResponse() - { - return $this->aLastResponse; - } - - /** - * @param mixed $aResult - * - * @return array - * - * @throws \MailSo\Imap\Exceptions\ResponseNotFoundException - * @throws \MailSo\Imap\Exceptions\InvalidResponseException - * @throws \MailSo\Imap\Exceptions\NegativeResponseException - */ - private function validateResponse($aResult) - { - if (!\is_array($aResult) || 0 === $iCnt = \count($aResult)) - { - $this->writeLogException( - new Exceptions\ResponseNotFoundException(), - \MailSo\Log\Enumerations\Type::WARNING, true); - } - - if ($aResult[$iCnt - 1]->ResponseType !== \MailSo\Imap\Enumerations\ResponseType::CONTINUATION) - { - if (!$aResult[$iCnt - 1]->IsStatusResponse) - { - $this->writeLogException( - new Exceptions\InvalidResponseException($aResult), - \MailSo\Log\Enumerations\Type::WARNING, true); - } - - if (\MailSo\Imap\Enumerations\ResponseStatus::OK !== $aResult[$iCnt - 1]->StatusOrIndex) - { - $this->writeLogException( - new Exceptions\NegativeResponseException($aResult), - \MailSo\Log\Enumerations\Type::WARNING, true); - } - } - - return $aResult; - } - - /** - * @param string $sEndTag = null - * @param bool $bFindCapa = false - * - * @return array|bool - */ - protected function parseResponse($sEndTag = null, $bFindCapa = false) - { - if (\is_resource($this->rConnect)) - { - $oImapResponse = null; - $sEndTag = (null === $sEndTag) ? $this->getCurrentTag() : $sEndTag; - - while (true) - { - $oImapResponse = Response::NewInstance(); - - $this->partialParseResponseBranch($oImapResponse); - - if ($oImapResponse) - { - if (\MailSo\Imap\Enumerations\ResponseType::UNKNOWN === $oImapResponse->ResponseType) - { - return false; - } - - if ($bFindCapa) - { - $this->initCapabilityImapResponse($oImapResponse); - } - - $this->aPartialResponses[] = $oImapResponse; - if ($sEndTag === $oImapResponse->Tag || \MailSo\Imap\Enumerations\ResponseType::CONTINUATION === $oImapResponse->ResponseType) - { - if (isset($this->aTagTimeouts[$sEndTag])) - { - $this->writeLog((\microtime(true) - $this->aTagTimeouts[$sEndTag]).' ('.$sEndTag.')', - \MailSo\Log\Enumerations\Type::TIME); - - unset($this->aTagTimeouts[$sEndTag]); - } - - break; - } - } - else - { - return false; - } - - unset($oImapResponse); - } - } - - $this->iResponseBufParsedPos = 0; - $this->aLastResponse = $this->aPartialResponses; - $this->aPartialResponses = array(); - - return $this->aLastResponse; - } - - /** - * @param string $sEndTag = null - * @param bool $bFindCapa = false - * - * @return array - */ - private function parseResponseWithValidation($sEndTag = null, $bFindCapa = false) - { - return $this->validateResponse($this->parseResponse($sEndTag, $bFindCapa)); - } - - /** - * @param \MailSo\Imap\Response $oImapResponse - * - * @return void - */ - private function initCapabilityImapResponse($oImapResponse) - { - if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oImapResponse->ResponseType - && \is_array($oImapResponse->ResponseList)) - { - $aList = null; - if (isset($oImapResponse->ResponseList[1]) && \is_string($oImapResponse->ResponseList[1]) && - 'CAPABILITY' === \strtoupper($oImapResponse->ResponseList[1])) - { - $aList = \array_slice($oImapResponse->ResponseList, 2); - } - else if ($oImapResponse->OptionalResponse && \is_array($oImapResponse->OptionalResponse) && - 1 < \count($oImapResponse->OptionalResponse) && \is_string($oImapResponse->OptionalResponse[0]) && - 'CAPABILITY' === \strtoupper($oImapResponse->OptionalResponse[0])) - { - $aList = \array_slice($oImapResponse->OptionalResponse, 1); - } - - if (\is_array($aList) && 0 < \count($aList)) - { - $this->aCapabilityItems = \array_map('strtoupper', $aList); - } - } - } - - /** - * @return array|string - * - * @throws \MailSo\Net\Exceptions\Exception - */ - private function partialParseResponseBranch(&$oImapResponse, $iStackIndex = -1, - $bTreatAsAtom = false, $sParentToken = '', $sOpenBracket = '') - { - $mNull = null; - - $iStackIndex++; - $iPos = $this->iResponseBufParsedPos; - - $sPreviousAtomUpperCase = null; - $bIsEndOfList = false; - $bIsClosingBracketSquare = false; - $iLiteralLen = 0; - $iBufferEndIndex = 0; - $iDebugCount = 0; - - $rImapLiteralStream = null; - - $bIsGotoDefault = false; - $bIsGotoLiteral = false; - $bIsGotoLiteralEnd = false; - $bIsGotoAtomBracket = false; - $bIsGotoNotAtomBracket = false; - - $bCountOneInited = false; - $bCountTwoInited = false; - - $sAtomBuilder = $bTreatAsAtom ? '' : null; - $aList = array(); - if (null !== $oImapResponse) - { - $aList =& $oImapResponse->ResponseList; - } - - while (!$bIsEndOfList) - { - $iDebugCount++; - if (100000 === $iDebugCount) - { - $this->Logger()->Write('PartialParseOver: '.$iDebugCount, \MailSo\Log\Enumerations\Type::ERROR); - } - - if ($this->bNeedNext) - { - $iPos = 0; - $this->getNextBuffer(); - $this->iResponseBufParsedPos = $iPos; - $this->bNeedNext = false; - } - - $sChar = null; - if ($bIsGotoDefault) - { - $sChar = 'GOTO_DEFAULT'; - $bIsGotoDefault = false; - } - else if ($bIsGotoLiteral) - { - $bIsGotoLiteral = false; - $bIsGotoLiteralEnd = true; - - if ($this->partialResponseLiteralCallbackCallable( - $sParentToken, null === $sPreviousAtomUpperCase ? '' : \strtoupper($sPreviousAtomUpperCase), $this->rConnect, $iLiteralLen)) - { - if (!$bTreatAsAtom) - { - $aList[] = ''; - } - } - else - { - $sLiteral = ''; - $iRead = $iLiteralLen; - - while (0 < $iRead) - { - $sAddRead = \fread($this->rConnect, $iRead); - if (false === $sAddRead) - { - $sLiteral = false; - break; - } - - $sLiteral .= $sAddRead; - $iRead -= \strlen($sAddRead); - - \MailSo\Base\Utils::ResetTimeLimit(); - } - - if (false !== $sLiteral) - { - $iLiteralSize = \strlen($sLiteral); - \MailSo\Base\Loader::IncStatistic('NetRead', $iLiteralSize); - if ($iLiteralLen !== $iLiteralSize) - { - $this->writeLog('Literal stream read warning "read '.$iLiteralSize.' of '. - $iLiteralLen.'" bytes', \MailSo\Log\Enumerations\Type::WARNING); - } - - if (!$bTreatAsAtom) - { - $aList[] = $sLiteral; - - if (\MailSo\Config::$LogSimpleLiterals) - { - $this->writeLog('{'.\strlen($sLiteral).'} '.$sLiteral, \MailSo\Log\Enumerations\Type::INFO); - } - } - } - else - { - $this->writeLog('Can\'t read imap stream', \MailSo\Log\Enumerations\Type::NOTE); - } - - unset($sLiteral); - } - - continue; - } - else if ($bIsGotoLiteralEnd) - { - $rImapLiteralStream = null; - $sPreviousAtomUpperCase = null; - $this->bNeedNext = true; - $bIsGotoLiteralEnd = false; - - continue; - } - else if ($bIsGotoAtomBracket) - { - if ($bTreatAsAtom) - { - $sAtomBlock = $this->partialParseResponseBranch($mNull, $iStackIndex, true, - null === $sPreviousAtomUpperCase ? '' : \strtoupper($sPreviousAtomUpperCase), $sOpenBracket); - - $sAtomBuilder .= $sAtomBlock; - $iPos = $this->iResponseBufParsedPos; - $sAtomBuilder .= ($bIsClosingBracketSquare) ? ']' : ')'; - } - - $sPreviousAtomUpperCase = null; - $bIsGotoAtomBracket = false; - - continue; - } - else if ($bIsGotoNotAtomBracket) - { - $aSubItems = $this->partialParseResponseBranch($mNull, $iStackIndex, false, - null === $sPreviousAtomUpperCase ? '' : \strtoupper($sPreviousAtomUpperCase), $sOpenBracket); - - $aList[] = $aSubItems; - $iPos = $this->iResponseBufParsedPos; - $sPreviousAtomUpperCase = null; - if (null !== $oImapResponse && $oImapResponse->IsStatusResponse) - { - $oImapResponse->OptionalResponse = $aSubItems; - - $bIsGotoDefault = true; - $bIsGotoNotAtomBracket = false; - continue; - } - $bIsGotoNotAtomBracket = false; - - continue; - } - else - { - $iBufferEndIndex = \strlen($this->sResponseBuffer) - 3; - $this->bResponseBufferChanged = false; - - if ($iPos > $iBufferEndIndex) - { - break; - } - - $sChar = $this->sResponseBuffer[$iPos]; - } - - switch (true) - { - case ']' === $sChar: - $iPos++; - $sPreviousAtomUpperCase = null; - $bIsEndOfList = true; - break; - case ')' === $sChar: - $iPos++; - $sPreviousAtomUpperCase = null; - $bIsEndOfList = true; - break; - case ' ' === $sChar: - if ($bTreatAsAtom) - { - $sAtomBuilder .= ' '; - } - $iPos++; - break; - case '[' === $sChar: - $bIsClosingBracketSquare = true; - case '(' === $sChar: - if ('(' === $sChar) - { - $bIsClosingBracketSquare = false; - } - - if ($bTreatAsAtom) - { - $sAtomBuilder .= $bIsClosingBracketSquare ? '[' : '('; - } - $iPos++; - - $this->iResponseBufParsedPos = $iPos; - if ($bTreatAsAtom) - { - $bIsGotoAtomBracket = true; - $sOpenBracket = $bIsClosingBracketSquare ? '[' : '('; - } - else - { - $bIsGotoNotAtomBracket = true; - $sOpenBracket = $bIsClosingBracketSquare ? '[' : '('; - } - break; - case '{' === $sChar: - $bIsLiteralParsed = false; - $mLiteralEndPos = \strpos($this->sResponseBuffer, '}', $iPos); - if (false !== $mLiteralEndPos && $mLiteralEndPos > $iPos) - { - $sLiteralLenAsString = \substr($this->sResponseBuffer, $iPos + 1, $mLiteralEndPos - $iPos - 1); - if (\is_numeric($sLiteralLenAsString)) - { - $iLiteralLen = (int) $sLiteralLenAsString; - $bIsLiteralParsed = true; - $iPos = $mLiteralEndPos + 3; - $bIsGotoLiteral = true; - break; - } - } - if (!$bIsLiteralParsed) - { - $iPos = $iBufferEndIndex; - } - $sPreviousAtomUpperCase = null; - break; - case '"' === $sChar: - $bIsQuotedParsed = false; - while (true) - { - $iClosingPos = $iPos + 1; - if ($iClosingPos > $iBufferEndIndex) - { - break; - } - - while (true) - { - $iClosingPos = \strpos($this->sResponseBuffer, '"', $iClosingPos); - if (false === $iClosingPos) - { - break; - } - - // TODO - $iClosingPosNext = $iClosingPos + 1; - if ( - isset($this->sResponseBuffer[$iClosingPosNext]) && - ' ' !== $this->sResponseBuffer[$iClosingPosNext] && - "\r" !== $this->sResponseBuffer[$iClosingPosNext] && - "\n" !== $this->sResponseBuffer[$iClosingPosNext] && - ']' !== $this->sResponseBuffer[$iClosingPosNext] && - ')' !== $this->sResponseBuffer[$iClosingPosNext] - ) - { - $iClosingPos++; - continue; - } - - $iSlashCount = 0; - while ('\\' === $this->sResponseBuffer[$iClosingPos - $iSlashCount - 1]) - { - $iSlashCount++; - } - - if ($iSlashCount % 2 == 1) - { - $iClosingPos++; - continue; - } - else - { - break; - } - } - - if (false === $iClosingPos) - { - break; - } - else - { -// $iSkipClosingPos = 0; - $bIsQuotedParsed = true; - if ($bTreatAsAtom) - { - $sAtomBuilder .= \strtr( - \substr($this->sResponseBuffer, $iPos, $iClosingPos - $iPos + 1), - array('\\\\' => '\\', '\\"' => '"') - ); - } - else - { - $aList[] = \strtr( - \substr($this->sResponseBuffer, $iPos + 1, $iClosingPos - $iPos - 1), - array('\\\\' => '\\', '\\"' => '"') - ); - } - - $iPos = $iClosingPos + 1; - break; - } - } - - if (!$bIsQuotedParsed) - { - $iPos = $iBufferEndIndex; - } - - $sPreviousAtomUpperCase = null; - break; - - case 'GOTO_DEFAULT' === $sChar: - default: - $iCharBlockStartPos = $iPos; - - if (null !== $oImapResponse && $oImapResponse->IsStatusResponse) - { - $iPos = $iBufferEndIndex; - - while ($iPos > $iCharBlockStartPos && $this->sResponseBuffer[$iCharBlockStartPos] === ' ') - { - $iCharBlockStartPos++; - } - } - - $bIsAtomDone = false; - while (!$bIsAtomDone && ($iPos <= $iBufferEndIndex)) - { - $sCharDef = $this->sResponseBuffer[$iPos]; - switch (true) - { - case '[' === $sCharDef: - if (null === $sAtomBuilder) - { - $sAtomBuilder = ''; - } - - $sAtomBuilder .= \substr($this->sResponseBuffer, $iCharBlockStartPos, $iPos - $iCharBlockStartPos + 1); - - $iPos++; - $this->iResponseBufParsedPos = $iPos; - - $sListBlock = $this->partialParseResponseBranch($mNull, $iStackIndex, true, - null === $sPreviousAtomUpperCase ? '' : \strtoupper($sPreviousAtomUpperCase), '['); - - if (null !== $sListBlock) - { - $sAtomBuilder .= $sListBlock.']'; - } - - $iPos = $this->iResponseBufParsedPos; - $iCharBlockStartPos = $iPos; - break; - case ' ' === $sCharDef: - case ')' === $sCharDef && '(' === $sOpenBracket: - case ']' === $sCharDef && '[' === $sOpenBracket: - $bIsAtomDone = true; - break; - default: - $iPos++; - break; - } - } - - if ($iPos > $iCharBlockStartPos || null !== $sAtomBuilder) - { - $sLastCharBlock = \substr($this->sResponseBuffer, $iCharBlockStartPos, $iPos - $iCharBlockStartPos); - if (null === $sAtomBuilder) - { - $aList[] = $sLastCharBlock; - $sPreviousAtomUpperCase = $sLastCharBlock; - } - else - { - $sAtomBuilder .= $sLastCharBlock; - - if (!$bTreatAsAtom) - { - $aList[] = $sAtomBuilder; - $sPreviousAtomUpperCase = $sAtomBuilder; - $sAtomBuilder = null; - } - } - - if (null !== $oImapResponse) - { -// if (1 === \count($aList)) - if (!$bCountOneInited && 1 === \count($aList)) -// if (isset($aList[0]) && !isset($aList[1])) // fast 1 === \count($aList) - { - $bCountOneInited = true; - - $oImapResponse->Tag = $aList[0]; - if ('+' === $oImapResponse->Tag) - { - $oImapResponse->ResponseType = \MailSo\Imap\Enumerations\ResponseType::CONTINUATION; - } - else if ('*' === $oImapResponse->Tag) - { - $oImapResponse->ResponseType = \MailSo\Imap\Enumerations\ResponseType::UNTAGGED; - } - else if ($this->getCurrentTag() === $oImapResponse->Tag) - { - $oImapResponse->ResponseType = \MailSo\Imap\Enumerations\ResponseType::TAGGED; - } - else - { - $oImapResponse->ResponseType = \MailSo\Imap\Enumerations\ResponseType::UNKNOWN; - } - } -// else if (2 === \count($aList)) - else if (!$bCountTwoInited && 2 === \count($aList)) -// else if (isset($aList[1]) && !isset($aList[2])) // fast 2 === \count($aList) - { - $bCountTwoInited = true; - - $oImapResponse->StatusOrIndex = strtoupper($aList[1]); - - if ($oImapResponse->StatusOrIndex == \MailSo\Imap\Enumerations\ResponseStatus::OK || - $oImapResponse->StatusOrIndex == \MailSo\Imap\Enumerations\ResponseStatus::NO || - $oImapResponse->StatusOrIndex == \MailSo\Imap\Enumerations\ResponseStatus::BAD || - $oImapResponse->StatusOrIndex == \MailSo\Imap\Enumerations\ResponseStatus::BYE || - $oImapResponse->StatusOrIndex == \MailSo\Imap\Enumerations\ResponseStatus::PREAUTH) - { - $oImapResponse->IsStatusResponse = true; - } - } - else if (\MailSo\Imap\Enumerations\ResponseType::CONTINUATION === $oImapResponse->ResponseType) - { - $oImapResponse->HumanReadable = $sLastCharBlock; - } - else if ($oImapResponse->IsStatusResponse) - { - $oImapResponse->HumanReadable = $sLastCharBlock; - } - } - } - } - } - - $this->iResponseBufParsedPos = $iPos; - if (null !== $oImapResponse) - { - $this->bNeedNext = true; - $this->iResponseBufParsedPos = 0; - } - - if (100000 < $iDebugCount) - { - $this->Logger()->Write('PartialParseOverResult: '.$iDebugCount, \MailSo\Log\Enumerations\Type::ERROR); - } - - return $bTreatAsAtom ? $sAtomBuilder : $aList; - } - - /** - * @param string $sParent - * @param string $sLiteralAtomUpperCase - * @param resource $rImapStream - * @param int $iLiteralLen - * - * @return bool - */ - private function partialResponseLiteralCallbackCallable($sParent, $sLiteralAtomUpperCase, $rImapStream, $iLiteralLen) - { - $sLiteralAtomUpperCasePeek = ''; - if (0 === \strpos($sLiteralAtomUpperCase, 'BODY')) - { - $sLiteralAtomUpperCasePeek = \str_replace('BODY', 'BODY.PEEK', $sLiteralAtomUpperCase); - } - - $sFetchKey = ''; - if (\is_array($this->aFetchCallbacks)) - { - if (0 < \strlen($sLiteralAtomUpperCasePeek) && isset($this->aFetchCallbacks[$sLiteralAtomUpperCasePeek])) - { - $sFetchKey = $sLiteralAtomUpperCasePeek; - } - else if (0 < \strlen($sLiteralAtomUpperCase) && isset($this->aFetchCallbacks[$sLiteralAtomUpperCase])) - { - $sFetchKey = $sLiteralAtomUpperCase; - } - } - - $bResult = false; - if (0 < \strlen($sFetchKey) && '' !== $this->aFetchCallbacks[$sFetchKey] && - \is_callable($this->aFetchCallbacks[$sFetchKey])) - { - $rImapLiteralStream = - \MailSo\Base\StreamWrappers\Literal::CreateStream($rImapStream, $iLiteralLen); - - $bResult = true; - $this->writeLog('Start Callback for '.$sParent.' / '.$sLiteralAtomUpperCase. - ' - try to read '.$iLiteralLen.' bytes.', \MailSo\Log\Enumerations\Type::NOTE); - - $this->bRunningCallback = true; - - try - { - \call_user_func($this->aFetchCallbacks[$sFetchKey], - $sParent, $sLiteralAtomUpperCase, $rImapLiteralStream); - } - catch (\Exception $oException) - { - $this->writeLog('Callback Exception', \MailSo\Log\Enumerations\Type::NOTICE); - $this->writeLogException($oException); - } - - if (\is_resource($rImapLiteralStream)) - { - $iNotReadLiteralLen = 0; - - $bFeof = \feof($rImapLiteralStream); - $this->writeLog('End Callback for '.$sParent.' / '.$sLiteralAtomUpperCase. - ' - feof = '.($bFeof ? 'good' : 'BAD'), $bFeof ? - \MailSo\Log\Enumerations\Type::NOTE : \MailSo\Log\Enumerations\Type::WARNING); - - if (!$bFeof) - { - while (!@\feof($rImapLiteralStream)) - { - $sBuf = @\fread($rImapLiteralStream, 1024 * 1024); - if (false === $sBuf || 0 === \strlen($sBuf) || null === $sBuf) - { - break; - } - - \MailSo\Base\Utils::ResetTimeLimit(); - $iNotReadLiteralLen += \strlen($sBuf); - } - - if (\is_resource($rImapLiteralStream) && !@\feof($rImapLiteralStream)) - { - @\stream_get_contents($rImapLiteralStream); - } - } - - if (\is_resource($rImapLiteralStream)) - { - @\fclose($rImapLiteralStream); - } - - if ($iNotReadLiteralLen > 0) - { - $this->writeLog('Not read literal size is '.$iNotReadLiteralLen.' bytes.', - \MailSo\Log\Enumerations\Type::WARNING); - } - } - else - { - $this->writeLog('Literal stream is not resource after callback.', - \MailSo\Log\Enumerations\Type::WARNING); - } - - \MailSo\Base\Loader::IncStatistic('NetRead', $iLiteralLen); - - $this->bRunningCallback = false; - } - - return $bResult; - } - - /** - * @param array $aParams = null - * - * @return string - */ - private function prepearParamLine($aParams = array()) - { - $sReturn = ''; - if (\is_array($aParams) && 0 < \count($aParams)) - { - foreach ($aParams as $mParamItem) - { - if (\is_array($mParamItem) && 0 < \count($mParamItem)) - { - $sReturn .= ' ('.\trim($this->prepearParamLine($mParamItem)).')'; - } - else if (\is_string($mParamItem)) - { - $sReturn .= ' '.$mParamItem; - } - } - } - return $sReturn; - } - - /** - * @return string - */ - private function getNewTag() - { - $this->iTagCount++; - return $this->getCurrentTag(); - } - - /** - * @return string - */ - private function getCurrentTag() - { - return self::TAG_PREFIX.$this->iTagCount; - } - - /** - * @param string $sStringForEscape - * - * @return string - */ - public function EscapeString($sStringForEscape) - { - return '"'.\str_replace(array('\\', '"'), array('\\\\', '\\"'), $sStringForEscape).'"'; - } - - /** - * @return string - */ - protected function getLogName() - { - return 'IMAP'; - } - - /** - * @param \MailSo\Log\Logger $oLogger - * - * @return \MailSo\Imap\ImapClient - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - */ - public function SetLogger($oLogger) - { - parent::SetLogger($oLogger); - - return $this; - } - - /** - * @param resource $rConnect - * @param array $aCapabilityItems = array() - * - * @return \MailSo\Imap\ImapClient - */ - public function TestSetValues($rConnect, $aCapabilityItems = array()) - { - $this->rConnect = $rConnect; - $this->aCapabilityItems = $aCapabilityItems; - - return $this; - } - - /** - * @param string $sEndTag = null - * @param string $bFindCapa = false - * - * @return array - */ - public function TestParseResponseWithValidationProxy($sEndTag = null, $bFindCapa = false) - { - return $this->parseResponseWithValidation($sEndTag, $bFindCapa); - } -} +iTagCount = 0; + $this->aCapabilityItems = null; + $this->oCurrentFolderInfo = null; + $this->aFetchCallbacks = null; + $this->iResponseBufParsedPos = 0; + + $this->aLastResponse = array(); + $this->bNeedNext = true; + $this->aPartialResponses = array(); + + $this->aTagTimeouts = array(); + + $this->bIsLoggined = false; + $this->bIsSelected = false; + $this->sLogginedUser = ''; + + $this->__FORCE_SELECT_ON_EXAMINE__ = false; + + @\ini_set('xdebug.max_nesting_level', 500); + } + + /** + * @return \MailSo\Imap\ImapClient + */ + public static function NewInstance() + { + return new self(); + } + + /** + * @return string + */ + public function GetLogginedUser() + { + return $this->sLogginedUser; + } + + /** + * @param string $sServerName + * @param int $iPort = 143 + * @param int $iSecurityType = \MailSo\Net\Enumerations\ConnectionSecurityType::AUTO_DETECT + * @param bool $bVerifySsl = false + * @param bool $bAllowSelfSigned = true + * + * @return \MailSo\Imap\ImapClient + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function Connect($sServerName, $iPort = 143, + $iSecurityType = \MailSo\Net\Enumerations\ConnectionSecurityType::AUTO_DETECT, + $bVerifySsl = false, $bAllowSelfSigned = true) + { + $this->aTagTimeouts['*'] = \microtime(true); + + parent::Connect($sServerName, $iPort, $iSecurityType, $bVerifySsl, $bAllowSelfSigned); + + $this->parseResponseWithValidation('*', true); + + if (\MailSo\Net\Enumerations\ConnectionSecurityType::UseStartTLS( + $this->IsSupported('STARTTLS'), $this->iSecurityType)) + { + $this->SendRequestWithCheck('STARTTLS'); + $this->EnableCrypto(); + + $this->aCapabilityItems = null; + } + else if (\MailSo\Net\Enumerations\ConnectionSecurityType::STARTTLS === $this->iSecurityType) + { + $this->writeLogException( + new \MailSo\Net\Exceptions\SocketUnsuppoterdSecureConnectionException('STARTTLS is not supported'), + \MailSo\Log\Enumerations\Type::ERROR, true); + } + + return $this; + } + + protected function _xor($string, $string2) + { + $result = ''; + $size = strlen($string); + for ($i=0; $i<$size; $i++) { + $result .= chr(ord($string[$i]) ^ ord($string2[$i])); + } + return $result; + } + + /** + * @param string $sLogin + * @param string $sPassword + * @param string $sProxyAuthUser = '' + * @param bool $bUseAuthPlainIfSupported = true + * @param bool $bUseAuthCramMd5IfSupported = true + * + * @return \MailSo\Imap\ImapClient + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function Login($sLogin, $sPassword, $sProxyAuthUser = '', + $bUseAuthPlainIfSupported = true, $bUseAuthCramMd5IfSupported = true) + { + if (!\MailSo\Base\Validator::NotEmptyString($sLogin, true) || + !\MailSo\Base\Validator::NotEmptyString($sPassword, true)) + { + $this->writeLogException( + new \MailSo\Base\Exceptions\InvalidArgumentException(), + \MailSo\Log\Enumerations\Type::ERROR, true); + } + + $sLogin = \MailSo\Base\Utils::IdnToAscii(\MailSo\Base\Utils::Trim($sLogin)); + + $sPassword = $sPassword; + + $this->sLogginedUser = $sLogin; + + try + { + if ($bUseAuthCramMd5IfSupported && $this->IsSupported('AUTH=CRAM-MD5')) + { + $this->SendRequest('AUTHENTICATE', array('CRAM-MD5')); + + $aResponse = $this->parseResponseWithValidation(); + if ($aResponse && \is_array($aResponse) && 0 < \count($aResponse) && + \MailSo\Imap\Enumerations\ResponseType::CONTINUATION === $aResponse[\count($aResponse) - 1]->ResponseType) + { + $oContinuationResponse = null; + foreach ($aResponse as $oResponse) + { + if ($oResponse && \MailSo\Imap\Enumerations\ResponseType::CONTINUATION === $oResponse->ResponseType) + { + $oContinuationResponse = $oResponse; + } + } + + if ($oContinuationResponse && !empty($oContinuationResponse->ResponseList[1])) + { + $sTicket = @\base64_decode($oContinuationResponse->ResponseList[1]); + $this->oLogger->Write('ticket: '.$sTicket); + + $sToken = \base64_encode($sLogin.' '.\MailSo\Base\Utils::Hmac($sTicket, $sPassword)); + + if ($this->oLogger) + { + $this->oLogger->AddSecret($sToken); + } + + $this->sendRaw($sToken, true, '*******'); + $this->parseResponseWithValidation(); + } + else + { + $this->writeLogException( + new \MailSo\Imap\Exceptions\LoginException(), + \MailSo\Log\Enumerations\Type::NOTICE, true); + } + } + else + { + $this->writeLogException( + new \MailSo\Imap\Exceptions\LoginException(), + \MailSo\Log\Enumerations\Type::NOTICE, true); + } + } + else if ($bUseAuthPlainIfSupported && $this->IsSupported('AUTH=PLAIN')) + { + $sToken = \base64_encode("\0".$sLogin."\0".$sPassword); + if ($this->oLogger) + { + $this->oLogger->AddSecret($sToken); + } + + if ($this->IsSupported('AUTH=SASL-IR') && false) + { + $this->SendRequestWithCheck('AUTHENTICATE', array('PLAIN', $sToken)); + } + else + { + $this->SendRequest('AUTHENTICATE', array('PLAIN')); + $this->parseResponseWithValidation(); + + $this->sendRaw($sToken, true, '*******'); + $this->parseResponseWithValidation(); + } + } + else + { + if ($this->oLogger) + { + $this->oLogger->AddSecret($this->EscapeString($sPassword)); + } + + $this->SendRequestWithCheck('LOGIN', + array( + $this->EscapeString($sLogin), + $this->EscapeString($sPassword) + )); + } +// else +// { +// $this->writeLogException( +// new \MailSo\Imap\Exceptions\LoginBadMethodException(), +// \MailSo\Log\Enumerations\Type::NOTICE, true); +// } + + if (0 < \strlen($sProxyAuthUser)) + { + $this->SendRequestWithCheck('PROXYAUTH', array($this->EscapeString($sProxyAuthUser))); + } + } + catch (\MailSo\Imap\Exceptions\NegativeResponseException $oException) + { + $this->writeLogException( + new \MailSo\Imap\Exceptions\LoginBadCredentialsException( + $oException->GetResponses(), '', 0, $oException), + \MailSo\Log\Enumerations\Type::NOTICE, true); + } + + $this->bIsLoggined = true; + $this->aCapabilityItems = null; + + return $this; + } + + /** + * @param string $sXOAuth2Token + * + * @return \MailSo\Imap\ImapClient + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function LoginWithXOauth2($sXOAuth2Token) + { + if (!\MailSo\Base\Validator::NotEmptyString($sXOAuth2Token, true)) + { + $this->writeLogException( + new \MailSo\Base\Exceptions\InvalidArgumentException(), + \MailSo\Log\Enumerations\Type::ERROR, true); + } + + if (!$this->IsSupported('AUTH=XOAUTH2')) + { + $this->writeLogException( + new \MailSo\Imap\Exceptions\LoginBadMethodException(), + \MailSo\Log\Enumerations\Type::NOTICE, true); + } + + try + { + $this->SendRequest('AUTHENTICATE', array('XOAUTH2', \trim($sXOAuth2Token))); + $aR = $this->parseResponseWithValidation(); + + if (\is_array($aR) && 0 < \count($aR) && isset($aR[\count($aR) - 1])) + { + $oR = $aR[\count($aR) - 1]; + if (\MailSo\Imap\Enumerations\ResponseType::CONTINUATION === $oR->ResponseType) + { + if (!empty($oR->ResponseList[1]) && preg_match('/^[a-zA-Z0-9=+\/]+$/', $oR->ResponseList[1])) + { + $this->Logger()->Write(\base64_decode($oR->ResponseList[1]), + \MailSo\Log\Enumerations\Type::WARNING); + } + + $this->sendRaw(''); + $this->parseResponseWithValidation(); + } + } + } + catch (\MailSo\Imap\Exceptions\NegativeResponseException $oException) + { + $this->writeLogException( + new \MailSo\Imap\Exceptions\LoginBadCredentialsException( + $oException->GetResponses(), '', 0, $oException), + \MailSo\Log\Enumerations\Type::NOTICE, true); + } + + $this->bIsLoggined = true; + $this->aCapabilityItems = null; + + return $this; + } + + /** + * @return \MailSo\Imap\ImapClient + * + * @throws \MailSo\Net\Exceptions\Exception + */ + public function Logout() + { + if ($this->bIsLoggined) + { + $this->bIsLoggined = false; + $this->SendRequestWithCheck('LOGOUT', array()); + } + + return $this; + } + + /** + * @return \MailSo\Imap\ImapClient + */ + public function ForceCloseConnection() + { + $this->Disconnect(); + + return $this; + } + + /** + * @return bool + */ + public function IsLoggined() + { + return $this->IsConnected() && $this->bIsLoggined; + } + + /** + * @return bool + */ + public function IsSelected() + { + return $this->IsLoggined() && $this->bIsSelected; + } + + /** + * @return array|null + * + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function Capability() + { + $this->SendRequestWithCheck('CAPABILITY', array(), true); + return $this->aCapabilityItems; + } + + /** + * @param string $sExtentionName + * @return bool + * + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function IsSupported($sExtentionName) + { + $bResult = \MailSo\Base\Validator::NotEmptyString($sExtentionName, true); + if ($bResult && null === $this->aCapabilityItems) + { + $this->aCapabilityItems = $this->Capability(); + } + + return $bResult && \is_array($this->aCapabilityItems) && + \in_array(\strtoupper($sExtentionName), $this->aCapabilityItems); + } + + /** + * @return \MailSo\Imap\NamespaceResult|null + * + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function GetNamespace() + { + if (!$this->IsSupported('NAMESPACE')) + { + return null; + } + + $oReturn = false; + + $this->SendRequest('NAMESPACE'); + $aResult = $this->parseResponseWithValidation(); + + $oImapResponse = null; + foreach ($aResult as /* @var $oImapResponse \MailSo\Imap\Response */ $oImapResponse) + { + if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oImapResponse->ResponseType && + 'NAMESPACE' === $oImapResponse->StatusOrIndex) + { + $oReturn = NamespaceResult::NewInstance(); + $oReturn->InitByImapResponse($oImapResponse); + break; + } + } + + if (false === $oReturn) + { + $this->writeLogException( + new \MailSo\Imap\Exceptions\ResponseException(), + \MailSo\Log\Enumerations\Type::ERROR, true); + } + + return $oReturn; + } + + /** + * @return \MailSo\Imap\ImapClient + * + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function Noop() + { + return $this->SendRequestWithCheck('NOOP'); + } + + /** + * @param string $sFolderName + * + * @return \MailSo\Imap\ImapClient + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function FolderCreate($sFolderName) + { + return $this->SendRequestWithCheck('CREATE', + array($this->EscapeString($sFolderName))); + } + + /** + * @param string $sFolderName + * + * @return \MailSo\Imap\ImapClient + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function FolderDelete($sFolderName) + { + return $this->SendRequestWithCheck('DELETE', + array($this->EscapeString($sFolderName))); + } + + /** + * @param string $sFolderName + * + * @return \MailSo\Imap\ImapClient + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function FolderSubscribe($sFolderName) + { + return $this->SendRequestWithCheck('SUBSCRIBE', + array($this->EscapeString($sFolderName))); + } + + /** + * @param string $sFolderName + * + * @return \MailSo\Imap\ImapClient + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function FolderUnSubscribe($sFolderName) + { + return $this->SendRequestWithCheck('UNSUBSCRIBE', + array($this->EscapeString($sFolderName))); + } + + /** + * @param string $sOldFolderName + * @param string $sNewFolderName + * + * @return \MailSo\Imap\ImapClient + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function FolderRename($sOldFolderName, $sNewFolderName) + { + return $this->SendRequestWithCheck('RENAME', array( + $this->EscapeString($sOldFolderName), + $this->EscapeString($sNewFolderName))); + } + + /** + * @param array $aResult + * + * @return array + */ + protected function getStatusFolderInformation($aResult) + { + $aReturn = array(); + + if (\is_array($aResult)) + { + $oImapResponse = null; + foreach ($aResult as /* @var $oImapResponse \MailSo\Imap\Response */ $oImapResponse) + { + if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oImapResponse->ResponseType && + 'STATUS' === $oImapResponse->StatusOrIndex && isset($oImapResponse->ResponseList[3]) && + \is_array($oImapResponse->ResponseList[3])) + { + $sName = null; + foreach ($oImapResponse->ResponseList[3] as $sArrayItem) + { + if (null === $sName) + { + $sName = $sArrayItem; + } + else + { + $aReturn[$sName] = $sArrayItem; + $sName = null; + } + } + } + } + } + + return $aReturn; + } + + /** + * @param string $sFolderName + * @param array $aStatusItems + * + * @return array|bool + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function FolderStatus($sFolderName, array $aStatusItems) + { + $aResult = false; + if (\count($aStatusItems) > 0) + { + $this->SendRequest('STATUS', + array($this->EscapeString($sFolderName), $aStatusItems)); + + $aResult = $this->getStatusFolderInformation( + $this->parseResponseWithValidation()); + } + + return $aResult; + } + + /** + * @param array $aResult + * @param string $sStatus + * @param bool $bUseListStatus = false + * + * @return array + */ + private function getFoldersFromResult(array $aResult, $sStatus, $bUseListStatus = false) + { + $aReturn = array(); + + $sDelimiter = ''; + $bInbox = false; + + $oImapResponse = null; + foreach ($aResult as /* @var $oImapResponse \MailSo\Imap\Response */ $oImapResponse) + { + if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oImapResponse->ResponseType && + $sStatus === $oImapResponse->StatusOrIndex && 5 === count($oImapResponse->ResponseList)) + { + try + { + $oFolder = Folder::NewInstance($oImapResponse->ResponseList[4], + $oImapResponse->ResponseList[3], $oImapResponse->ResponseList[2]); + + if ($oFolder->IsInbox()) + { + $bInbox = true; + } + + if (empty($sDelimiter)) + { + $sDelimiter = $oFolder->Delimiter(); + } + + $aReturn[] = $oFolder; + } + catch (\MailSo\Base\Exceptions\InvalidArgumentException $oException) + { + $this->writeLogException($oException, \MailSo\Log\Enumerations\Type::WARNING, false); + } + } + } + + if (!$bInbox && !empty($sDelimiter)) + { + $aReturn[] = Folder::NewInstance('INBOX', $sDelimiter); + } + + if ($bUseListStatus) + { + foreach ($aResult as /* @var $oImapResponse \MailSo\Imap\Response */ $oImapResponse) + { + if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oImapResponse->ResponseType && + 'STATUS' === $oImapResponse->StatusOrIndex && + isset($oImapResponse->ResponseList[2]) && + isset($oImapResponse->ResponseList[3]) && + \is_array($oImapResponse->ResponseList[3])) + { + $sFolderNameRaw = $oImapResponse->ResponseList[2]; + + $oCurrentFolder = null; + foreach ($aReturn as &$oFolder) + { + if ($oFolder && $sFolderNameRaw === $oFolder->FullNameRaw()) + { + $oCurrentFolder =& $oFolder; + break; + } + } + + if (null !== $oCurrentFolder) + { + $sName = null; + $aStatus = array(); + + foreach ($oImapResponse->ResponseList[3] as $sArrayItem) + { + if (null === $sName) + { + $sName = $sArrayItem; + } + else + { + $aStatus[$sName] = $sArrayItem; + $sName = null; + } + } + + if (0 < count($aStatus)) + { + $oCurrentFolder->SetExtended('STATUS', $aStatus); + } + } + + unset($oCurrentFolder); + } + } + } + + return $aReturn; + } + + /** + * @param bool $bIsSubscribeList + * @param string $sParentFolderName = '' + * @param string $sListPattern = '*' + * @param bool $bUseListStatus = false + * + * @return array + * + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + private function specificFolderList($bIsSubscribeList, $sParentFolderName = '', $sListPattern = '*', $bUseListStatus = false) + { + $sCmd = 'LSUB'; + if (!$bIsSubscribeList) + { + $sCmd = 'LIST'; + } + + $sListPattern = 0 === strlen(trim($sListPattern)) ? '*' : $sListPattern; + + $aParameters = array( + $this->EscapeString($sParentFolderName), + $this->EscapeString($sListPattern) + ); + + if ($bUseListStatus && !$bIsSubscribeList && $this->IsSupported('LIST-STATUS')) + { + $aL = array( + \MailSo\Imap\Enumerations\FolderStatus::MESSAGES, + \MailSo\Imap\Enumerations\FolderStatus::UNSEEN, + \MailSo\Imap\Enumerations\FolderStatus::UIDNEXT + ); + +// if ($this->IsSupported('CONDSTORE')) +// { +// $aL[] = \MailSo\Imap\Enumerations\FolderStatus::HIGHESTMODSEQ; +// } + + $aParameters[] = 'RETURN'; + $aParameters[] = array('STATUS', $aL); + } + else + { + $bUseListStatus = false; + } + + $this->SendRequest($sCmd, $aParameters); + + return $this->getFoldersFromResult( + $this->parseResponseWithValidation(), $sCmd, $bUseListStatus); + } + + /** + * @param string $sParentFolderName = '' + * @param string $sListPattern = '*' + * + * @return array + * + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function FolderList($sParentFolderName = '', $sListPattern = '*') + { + return $this->specificFolderList(false, $sParentFolderName, $sListPattern); + } + + /** + * @param string $sParentFolderName = '' + * @param string $sListPattern = '*' + * + * @return array + * + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function FolderSubscribeList($sParentFolderName = '', $sListPattern = '*') + { + return $this->specificFolderList(true, $sParentFolderName, $sListPattern); + } + + /** + * @param string $sParentFolderName = '' + * @param string $sListPattern = '*' + * + * @return array + * + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function FolderStatusList($sParentFolderName = '', $sListPattern = '*') + { + return $this->specificFolderList(false, $sParentFolderName, $sListPattern, true); + } + + /** + * @param array $aResult + * @param string $sFolderName + * @param bool $bIsWritable + * + * @return void + */ + protected function initCurrentFolderInformation($aResult, $sFolderName, $bIsWritable) + { + if (\is_array($aResult)) + { + $oImapResponse = null; + $oResult = FolderInformation::NewInstance($sFolderName, $bIsWritable); + + foreach ($aResult as /* @var $oImapResponse \MailSo\Imap\Response */ $oImapResponse) + { + if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oImapResponse->ResponseType) + { + if (\count($oImapResponse->ResponseList) > 2 && + 'FLAGS' === $oImapResponse->ResponseList[1] && \is_array($oImapResponse->ResponseList[2])) + { + $oResult->Flags = $oImapResponse->ResponseList[2]; + } + + if (is_array($oImapResponse->OptionalResponse) && \count($oImapResponse->OptionalResponse) > 1) + { + if ('PERMANENTFLAGS' === $oImapResponse->OptionalResponse[0] && + is_array($oImapResponse->OptionalResponse[1])) + { + $oResult->PermanentFlags = $oImapResponse->OptionalResponse[1]; + } + else if ('UIDVALIDITY' === $oImapResponse->OptionalResponse[0] && + isset($oImapResponse->OptionalResponse[1])) + { + $oResult->Uidvalidity = $oImapResponse->OptionalResponse[1]; + } + else if ('UNSEEN' === $oImapResponse->OptionalResponse[0] && + isset($oImapResponse->OptionalResponse[1]) && + is_numeric($oImapResponse->OptionalResponse[1])) + { + $oResult->Unread = (int) $oImapResponse->OptionalResponse[1]; + } + else if ('UIDNEXT' === $oImapResponse->OptionalResponse[0] && + isset($oImapResponse->OptionalResponse[1])) + { + $oResult->Uidnext = $oImapResponse->OptionalResponse[1]; + } + else if ('HIGHESTMODSEQ' === $oImapResponse->OptionalResponse[0] && + isset($oImapResponse->OptionalResponse[1]) && + \is_numeric($oImapResponse->OptionalResponse[1])) + { + $oResult->HighestModSeq = \trim($oImapResponse->OptionalResponse[1]); + } + } + + if (\count($oImapResponse->ResponseList) > 2 && + \is_string($oImapResponse->ResponseList[2]) && + \is_numeric($oImapResponse->ResponseList[1])) + { + switch($oImapResponse->ResponseList[2]) + { + case 'EXISTS': + $oResult->Exists = (int) $oImapResponse->ResponseList[1]; + break; + case 'RECENT': + $oResult->Recent = (int) $oImapResponse->ResponseList[1]; + break; + } + } + } + } + + $this->oCurrentFolderInfo = $oResult; + } + } + + /** + * @param string $sFolderName + * @param bool $bIsWritable + * @param bool $bReSelectSameFolders + * + * @return \MailSo\Imap\ImapClient + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + protected function selectOrExamineFolder($sFolderName, $bIsWritable, $bReSelectSameFolders) + { + if (!$bReSelectSameFolders) + { + if ($this->oCurrentFolderInfo && + $sFolderName === $this->oCurrentFolderInfo->FolderName && + $bIsWritable === $this->oCurrentFolderInfo->IsWritable) + { + return $this; + } + } + + if (!\MailSo\Base\Validator::NotEmptyString($sFolderName, true)) + { + throw new \MailSo\Base\Exceptions\InvalidArgumentException(); + } + + $this->SendRequest(($bIsWritable) ? 'SELECT' : 'EXAMINE', + array($this->EscapeString($sFolderName))); + + $this->initCurrentFolderInformation( + $this->parseResponseWithValidation(), $sFolderName, $bIsWritable); + + $this->bIsSelected = true; + + return $this; + } + + /** + * @param string $sFolderName + * @param bool $bReSelectSameFolders = false + * + * @return \MailSo\Imap\ImapClient + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function FolderSelect($sFolderName, $bReSelectSameFolders = false) + { + return $this->selectOrExamineFolder($sFolderName, true, $bReSelectSameFolders); + } + + /** + * @param string $sFolderName + * @param bool $bReSelectSameFolders = false + * + * @return \MailSo\Imap\ImapClient + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function FolderExamine($sFolderName, $bReSelectSameFolders = false) + { + return $this->selectOrExamineFolder($sFolderName, $this->__FORCE_SELECT_ON_EXAMINE__, $bReSelectSameFolders); + } + + /** + * @return \MailSo\Imap\ImapClient + * + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function FolderUnSelect() + { + if ($this->IsSelected() && $this->IsSupported('UNSELECT')) + { + $this->SendRequestWithCheck('UNSELECT'); + $this->bIsSelected = false; + } + + return $this; + } + + /** + * @param array $aInputFetchItems + * @param string $sIndexRange + * @param bool $bIndexIsUid + * + * @return array + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function Fetch(array $aInputFetchItems, $sIndexRange, $bIndexIsUid) + { + $sIndexRange = (string) $sIndexRange; + if (!\MailSo\Base\Validator::NotEmptyString($sIndexRange, true)) + { + $this->writeLogException( + new \MailSo\Base\Exceptions\InvalidArgumentException(), + \MailSo\Log\Enumerations\Type::ERROR, true); + } + + $aFetchItems = \MailSo\Imap\Enumerations\FetchType::ChangeFetchItemsBefourRequest($aInputFetchItems); + foreach ($aFetchItems as $sName => $mItem) + { + if (0 < \strlen($sName) && '' !== $mItem) + { + if (null === $this->aFetchCallbacks) + { + $this->aFetchCallbacks = array(); + } + + $this->aFetchCallbacks[$sName] = $mItem; + } + } + + $this->SendRequest((($bIndexIsUid) ? 'UID ' : '').'FETCH', array($sIndexRange, \array_keys($aFetchItems))); + $aResult = $this->validateResponse($this->parseResponse()); + $this->aFetchCallbacks = null; + + $aReturn = array(); + $oImapResponse = null; + foreach ($aResult as $oImapResponse) + { + if (FetchResponse::IsValidFetchImapResponse($oImapResponse)) + { + if (FetchResponse::IsNotEmptyFetchImapResponse($oImapResponse)) + { + $aReturn[] = FetchResponse::NewInstance($oImapResponse); + } + else + { + if ($this->oLogger) + { + $this->oLogger->Write('Skipped Imap Response! ['.$oImapResponse->ToLine().']', \MailSo\Log\Enumerations\Type::NOTICE); + } + } + } + } + + return $aReturn; + } + + + /** + * @return array|false + * + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function Quota() + { + $aReturn = false; + if ($this->IsSupported('QUOTA')) + { + $this->SendRequest('GETQUOTAROOT "INBOX"'); + $aResult = $this->parseResponseWithValidation(); + + $aReturn = array(0, 0); + $oImapResponse = null; + foreach ($aResult as /* @var $oImapResponse \MailSo\Imap\Response */ $oImapResponse) + { + if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oImapResponse->ResponseType + && 'QUOTA' === $oImapResponse->StatusOrIndex + && \is_array($oImapResponse->ResponseList) + && isset($oImapResponse->ResponseList[3]) + && \is_array($oImapResponse->ResponseList[3]) + && 2 < \count($oImapResponse->ResponseList[3]) + && 'STORAGE' === \strtoupper($oImapResponse->ResponseList[3][0]) + && \is_numeric($oImapResponse->ResponseList[3][1]) + && \is_numeric($oImapResponse->ResponseList[3][2]) + ) + { + $aReturn = array( + (int) $oImapResponse->ResponseList[3][1], + (int) $oImapResponse->ResponseList[3][2], + 0, + 0 + ); + + if (5 < \count($oImapResponse->ResponseList[3]) + && 'MESSAGE' === \strtoupper($oImapResponse->ResponseList[3][3]) + && \is_numeric($oImapResponse->ResponseList[3][4]) + && \is_numeric($oImapResponse->ResponseList[3][5]) + ) + { + $aReturn[2] = (int) $oImapResponse->ResponseList[3][4]; + $aReturn[3] = (int) $oImapResponse->ResponseList[3][5]; + } + } + } + } + + return $aReturn; + } + + /** + * @param array $aSortTypes + * @param string $sSearchCriterias + * @param bool $bReturnUid + * + * @return array + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function MessageSimpleSort($aSortTypes, $sSearchCriterias = 'ALL', $bReturnUid = true) + { + $sCommandPrefix = ($bReturnUid) ? 'UID ' : ''; + $sSearchCriterias = !\MailSo\Base\Validator::NotEmptyString($sSearchCriterias, true) || '*' === $sSearchCriterias + ? 'ALL' : $sSearchCriterias; + + if (!\is_array($aSortTypes) || 0 === \count($aSortTypes)) + { + $this->writeLogException( + new \MailSo\Base\Exceptions\InvalidArgumentException(), + \MailSo\Log\Enumerations\Type::ERROR, true); + } + else if (!$this->IsSupported('SORT')) + { + $this->writeLogException( + new \MailSo\Base\Exceptions\InvalidArgumentException(), + \MailSo\Log\Enumerations\Type::ERROR, true); + } + + $aRequest = array(); + $aRequest[] = $aSortTypes; + $aRequest[] = \MailSo\Base\Utils::IsAscii($sSearchCriterias) ? 'US-ASCII' : 'UTF-8'; + $aRequest[] = $sSearchCriterias; + + $sCmd = 'SORT'; + + $this->SendRequest($sCommandPrefix.$sCmd, $aRequest); + $aResult = $this->parseResponseWithValidation(); + + $aReturn = array(); + $oImapResponse = null; + foreach ($aResult as /* @var $oImapResponse \MailSo\Imap\Response */ $oImapResponse) + { + if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oImapResponse->ResponseType + && ($sCmd === $oImapResponse->StatusOrIndex || + ($bReturnUid && 'UID' === $oImapResponse->StatusOrIndex) && !empty($oImapResponse->ResponseList[2]) && + $sCmd === $oImapResponse->ResponseList[2]) + && \is_array($oImapResponse->ResponseList) + && 2 < \count($oImapResponse->ResponseList)) + { + $iStart = 2; + if ($bReturnUid && 'UID' === $oImapResponse->StatusOrIndex && + !empty($oImapResponse->ResponseList[2]) && + $sCmd === $oImapResponse->ResponseList[2]) + { + $iStart = 3; + } + + for ($iIndex = $iStart, $iLen = \count($oImapResponse->ResponseList); $iIndex < $iLen; $iIndex++) + { + $aReturn[] = (int) $oImapResponse->ResponseList[$iIndex]; + } + } + } + + return $aReturn; + } + + /** + * @param bool $bSort = false + * @param string $sSearchCriterias = 'ALL' + * @param array $aSearchOrSortReturn = null + * @param bool $bReturnUid = true + * @param string $sLimit = '' + * @param string $sCharset = '' + * @param array $aSortTypes = null + * + * @return array + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + private function simpleESearchOrESortHelper($bSort = false, $sSearchCriterias = 'ALL', $aSearchOrSortReturn = null, $bReturnUid = true, $sLimit = '', $sCharset = '', $aSortTypes = null) + { + $sCommandPrefix = ($bReturnUid) ? 'UID ' : ''; + $sSearchCriterias = 0 === \strlen($sSearchCriterias) || '*' === $sSearchCriterias + ? 'ALL' : $sSearchCriterias; + + $sCmd = $bSort ? 'SORT': 'SEARCH'; + if ($bSort && (!\is_array($aSortTypes) || 0 === \count($aSortTypes) || !$this->IsSupported('SORT'))) + { + $this->writeLogException( + new \MailSo\Base\Exceptions\InvalidArgumentException(), + \MailSo\Log\Enumerations\Type::ERROR, true); + } + + if (!$this->IsSupported($bSort ? 'ESORT' : 'ESEARCH')) + { + $this->writeLogException( + new \MailSo\Base\Exceptions\InvalidArgumentException(), + \MailSo\Log\Enumerations\Type::ERROR, true); + } + + if (!\is_array($aSearchOrSortReturn) || 0 === \count($aSearchOrSortReturn)) + { + $aSearchOrSortReturn = array('ALL'); + } + + $aRequest = array(); + if ($bSort) + { + $aRequest[] = 'RETURN'; + $aRequest[] = $aSearchOrSortReturn; + + $aRequest[] = $aSortTypes; + $aRequest[] = \MailSo\Base\Utils::IsAscii($sSearchCriterias) ? 'US-ASCII' : 'UTF-8'; + } + else + { + if (0 < \strlen($sCharset)) + { + $aRequest[] = 'CHARSET'; + $aRequest[] = \strtoupper($sCharset); + } + + $aRequest[] = 'RETURN'; + $aRequest[] = $aSearchOrSortReturn; + } + + $aRequest[] = $sSearchCriterias; + + if (0 < \strlen($sLimit)) + { + $aRequest[] = $sLimit; + } + + $this->SendRequest($sCommandPrefix.$sCmd, $aRequest); + $sRequestTag = $this->getCurrentTag(); + + $aResult = array(); + $aResponse = $this->parseResponseWithValidation(); + + if (\is_array($aResponse)) + { + $oImapResponse = null; + foreach ($aResponse as /* @var $oImapResponse \MailSo\Imap\Response */ $oImapResponse) + { + if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oImapResponse->ResponseType + && ('ESEARCH' === $oImapResponse->StatusOrIndex || 'ESORT' === $oImapResponse->StatusOrIndex) + && \is_array($oImapResponse->ResponseList) + && isset($oImapResponse->ResponseList[2], $oImapResponse->ResponseList[2][0], $oImapResponse->ResponseList[2][1]) + && 'TAG' === $oImapResponse->ResponseList[2][0] && $sRequestTag === $oImapResponse->ResponseList[2][1] + && (!$bReturnUid || ($bReturnUid && !empty($oImapResponse->ResponseList[3]) && 'UID' === $oImapResponse->ResponseList[3])) + ) + { + $iStart = 3; + foreach ($oImapResponse->ResponseList as $iIndex => $mItem) + { + if ($iIndex >= $iStart) + { + switch ($mItem) + { + case 'ALL': + case 'MAX': + case 'MIN': + case 'COUNT': + if (isset($oImapResponse->ResponseList[$iIndex + 1])) + { + $aResult[$mItem] = $oImapResponse->ResponseList[$iIndex + 1]; + } + break; + } + } + } + } + } + } + + return $aResult; + } + + /** + * @param string $sSearchCriterias = 'ALL' + * @param array $aSearchReturn = null + * @param bool $bReturnUid = true + * @param string $sLimit = '' + * @param string $sCharset = '' + * + * @return array + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function MessageSimpleESearch($sSearchCriterias = 'ALL', $aSearchReturn = null, $bReturnUid = true, $sLimit = '', $sCharset = '') + { + return $this->simpleESearchOrESortHelper(false, $sSearchCriterias, $aSearchReturn, $bReturnUid, $sLimit, $sCharset); + } + + /** + * @param array $aSortTypes + * @param string $sSearchCriterias = 'ALL' + * @param array $aSearchReturn = null + * @param bool $bReturnUid = true + * @param string $sLimit = '' + * + * @return array + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function MessageSimpleESort($aSortTypes, $sSearchCriterias = 'ALL', $aSearchReturn = null, $bReturnUid = true, $sLimit = '') + { + return $this->simpleESearchOrESortHelper(true, $sSearchCriterias, $aSearchReturn, $bReturnUid, $sLimit, '', $aSortTypes); + } + + /** + * @param array $aResult + * @return \MailSo\Imap\Response + */ + private function findLastResponse($aResult) + { + $oResult = null; + if (\is_array($aResult) && 0 < \count($aResult)) + { + $oResult = $aResult[\count($aResult) - 1]; + if (!($oResult instanceof \MailSo\Imap\Response)) + { + $oResult = null; + } + } + + return $oResult; + } + + /** + * @param string $sSearchCriterias + * @param bool $bReturnUid = true + * @param string $sCharset = '' + * + * @return array + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function MessageSimpleSearch($sSearchCriterias = 'ALL', $bReturnUid = true, $sCharset = '') + { + $sCommandPrefix = ($bReturnUid) ? 'UID ' : ''; + $sSearchCriterias = 0 === \strlen($sSearchCriterias) || '*' === $sSearchCriterias + ? 'ALL' : $sSearchCriterias; + + $aRequest = array(); + if (0 < \strlen($sCharset)) + { + $aRequest[] = 'CHARSET'; + $aRequest[] = \strtoupper($sCharset); + } + + $aRequest[] = $sSearchCriterias; + + $sCmd = 'SEARCH'; + + $sCont = $this->SendRequest($sCommandPrefix.$sCmd, $aRequest, true); + if ('' !== $sCont) + { + $aResult = $this->parseResponseWithValidation(); + $oItem = $this->findLastResponse($aResult); + + if ($oItem && \MailSo\Imap\Enumerations\ResponseType::CONTINUATION === $oItem->ResponseType) + { + $aParts = explode("\r\n", $sCont); + foreach ($aParts as $sLine) + { + $this->sendRaw($sLine); + + $aResult = $this->parseResponseWithValidation(); + $oItem = $this->findLastResponse($aResult); + if ($oItem && \MailSo\Imap\Enumerations\ResponseType::CONTINUATION === $oItem->ResponseType) + { + continue; + } + } + } + } + else + { + $aResult = $this->parseResponseWithValidation(); + } + + $aReturn = array(); + $oImapResponse = null; + foreach ($aResult as /* @var $oImapResponse \MailSo\Imap\Response */ $oImapResponse) + { + if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oImapResponse->ResponseType + && ($sCmd === $oImapResponse->StatusOrIndex || + ($bReturnUid && 'UID' === $oImapResponse->StatusOrIndex) && !empty($oImapResponse->ResponseList[2]) && + $sCmd === $oImapResponse->ResponseList[2]) + && \is_array($oImapResponse->ResponseList) + && 2 < count($oImapResponse->ResponseList)) + { + $iStart = 2; + if ($bReturnUid && 'UID' === $oImapResponse->StatusOrIndex && + !empty($oImapResponse->ResponseList[2]) && + $sCmd === $oImapResponse->ResponseList[2]) + { + $iStart = 3; + } + + for ($iIndex = $iStart, $iLen = \count($oImapResponse->ResponseList); $iIndex < $iLen; $iIndex++) + { + $aReturn[] = (int) $oImapResponse->ResponseList[$iIndex]; + } + } + } + + $aReturn = \array_reverse($aReturn); + return $aReturn; + } + + /** + * @param mixed $aValue + * + * @return mixed + */ + private function validateThreadItem($aValue) + { + $mResult = false; + if (\is_numeric($aValue)) + { + $mResult = (int) $aValue; + if (0 >= $mResult) + { + $mResult = false; + } + } + else if (\is_array($aValue)) + { + if (1 === \count($aValue) && \is_numeric($aValue[0])) + { + $mResult = (int) $aValue[0]; + if (0 >= $mResult) + { + $mResult = false; + } + } + else + { + $mResult = array(); + foreach ($aValue as $aValueItem) + { + $mTemp = $this->validateThreadItem($aValueItem); + if (false !== $mTemp) + { + $mResult[] = $mTemp; + } + } + } + } + + return $mResult; + } + + /** + * @param string $sSearchCriterias = 'ALL' + * @param bool $bReturnUid = true + * @param string $sCharset = \MailSo\Base\Enumerations\Charset::UTF_8 + * + * @return array + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function MessageSimpleThread($sSearchCriterias = 'ALL', $bReturnUid = true, $sCharset = \MailSo\Base\Enumerations\Charset::UTF_8) + { + $sCommandPrefix = ($bReturnUid) ? 'UID ' : ''; + $sSearchCriterias = !\MailSo\Base\Validator::NotEmptyString($sSearchCriterias, true) || '*' === $sSearchCriterias + ? 'ALL' : $sSearchCriterias; + + $sThreadType = ''; + switch (true) + { + case $this->IsSupported('THREAD=REFS'): + $sThreadType = 'REFS'; + break; + case $this->IsSupported('THREAD=REFERENCES'): + $sThreadType = 'REFERENCES'; + break; + case $this->IsSupported('THREAD=ORDEREDSUBJECT'): + $sThreadType = 'ORDEREDSUBJECT'; + break; + default: + $this->writeLogException( + new Exceptions\RuntimeException('Thread is not supported'), + \MailSo\Log\Enumerations\Type::ERROR, true); + break; + } + + $aRequest = array(); + $aRequest[] = $sThreadType; + $aRequest[] = \strtoupper($sCharset); + $aRequest[] = $sSearchCriterias; + + $sCmd = 'THREAD'; + + $this->SendRequest($sCommandPrefix.$sCmd, $aRequest); + $aResult = $this->parseResponseWithValidation(); + + $aReturn = array(); + $oImapResponse = null; + + foreach ($aResult as /* @var $oImapResponse \MailSo\Imap\Response */ $oImapResponse) + { + if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oImapResponse->ResponseType + && ($sCmd === $oImapResponse->StatusOrIndex || + ($bReturnUid && 'UID' === $oImapResponse->StatusOrIndex) && !empty($oImapResponse->ResponseList[2]) && + $sCmd === $oImapResponse->ResponseList[2]) + && \is_array($oImapResponse->ResponseList) + && 2 < \count($oImapResponse->ResponseList)) + { + $iStart = 2; + if ($bReturnUid && 'UID' === $oImapResponse->StatusOrIndex && + !empty($oImapResponse->ResponseList[2]) && + $sCmd === $oImapResponse->ResponseList[2]) + { + $iStart = 3; + } + + for ($iIndex = $iStart, $iLen = \count($oImapResponse->ResponseList); $iIndex < $iLen; $iIndex++) + { + $aNewValue = $this->validateThreadItem($oImapResponse->ResponseList[$iIndex]); + if (false !== $aNewValue) + { + $aReturn[] = $aNewValue; + } + } + } + } + + return $aReturn; + } + + /** + * @param string $sToFolder + * @param string $sIndexRange + * @param bool $bIndexIsUid + * + * @return \MailSo\Imap\ImapClient + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function MessageCopy($sToFolder, $sIndexRange, $bIndexIsUid) + { + if (0 === \strlen($sIndexRange)) + { + $this->writeLogException( + new \MailSo\Base\Exceptions\InvalidArgumentException(), + \MailSo\Log\Enumerations\Type::ERROR, true); + } + + $sCommandPrefix = ($bIndexIsUid) ? 'UID ' : ''; + return $this->SendRequestWithCheck($sCommandPrefix.'COPY', + array($sIndexRange, $this->EscapeString($sToFolder))); + } + + /** + * @param string $sToFolder + * @param string $sIndexRange + * @param bool $bIndexIsUid + * + * @return \MailSo\Imap\ImapClient + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function MessageMove($sToFolder, $sIndexRange, $bIndexIsUid) + { + if (0 === \strlen($sIndexRange)) + { + $this->writeLogException( + new \MailSo\Base\Exceptions\InvalidArgumentException(), + \MailSo\Log\Enumerations\Type::ERROR, true); + } + + if (!$this->IsSupported('MOVE')) + { + $this->writeLogException( + new Exceptions\RuntimeException('Move is not supported'), + \MailSo\Log\Enumerations\Type::ERROR, true); + } + + $sCommandPrefix = ($bIndexIsUid) ? 'UID ' : ''; + return $this->SendRequestWithCheck($sCommandPrefix.'MOVE', + array($sIndexRange, $this->EscapeString($sToFolder))); + } + + /** + * @param string $sUidRangeIfSupported = '' + * @param bool $bForceUidExpunge = false + * @param bool $bExpungeAll = false + * + * @return \MailSo\Imap\ImapClient + * + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function MessageExpunge($sUidRangeIfSupported = '', $bForceUidExpunge = false, $bExpungeAll = false) + { + $sUidRangeIfSupported = \trim($sUidRangeIfSupported); + + $sCmd = 'EXPUNGE'; + $aArguments = array(); + + if (!$bExpungeAll && $bForceUidExpunge && 0 < \strlen($sUidRangeIfSupported) && $this->IsSupported('UIDPLUS')) + { + $sCmd = 'UID '.$sCmd; + $aArguments = array($sUidRangeIfSupported); + } + + return $this->SendRequestWithCheck($sCmd, $aArguments); + } + + /** + * @param string $sIndexRange + * @param bool $bIndexIsUid + * @param array $aInputStoreItems + * @param string $sStoreAction + * + * @return \MailSo\Imap\ImapClient + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function MessageStoreFlag($sIndexRange, $bIndexIsUid, $aInputStoreItems, $sStoreAction) + { + if (!\MailSo\Base\Validator::NotEmptyString($sIndexRange, true) || + !\MailSo\Base\Validator::NotEmptyString($sStoreAction, true) || + 0 === \count($aInputStoreItems)) + { + return false; + } + + $sCmd = ($bIndexIsUid) ? 'UID STORE' : 'STORE'; + return $this->SendRequestWithCheck($sCmd, array($sIndexRange, $sStoreAction, $aInputStoreItems)); + } + + /** + * @param string $sFolderName + * @param resource $rMessageAppendStream + * @param int $iStreamSize + * @param array $aAppendFlags = null + * @param int $iUid = null + * @param int $sDateTime = 0 + * + * @return \MailSo\Imap\ImapClient + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function MessageAppendStream($sFolderName, $rMessageAppendStream, $iStreamSize, $aAppendFlags = null, &$iUid = null, $sDateTime = 0) + { + $aData = array($this->EscapeString($sFolderName), $aAppendFlags); + if (0 < $sDateTime) + { + $aData[] = $this->EscapeString(\gmdate('d-M-Y H:i:s', $sDateTime).' +0000'); + } + + $aData[] = '{'.$iStreamSize.'}'; + + $this->SendRequest('APPEND', $aData); + $this->parseResponseWithValidation(); + + $this->writeLog('Write to connection stream', \MailSo\Log\Enumerations\Type::NOTE); + + \MailSo\Base\Utils::MultipleStreamWriter($rMessageAppendStream, array($this->rConnect)); + + $this->sendRaw(''); + $this->parseResponseWithValidation(); + + if (null !== $iUid) + { + $aLastResponse = $this->GetLastResponse(); + if (\is_array($aLastResponse) && 0 < \count($aLastResponse) && $aLastResponse[\count($aLastResponse) - 1]) + { + $oLast = $aLastResponse[count($aLastResponse) - 1]; + if ($oLast && \MailSo\Imap\Enumerations\ResponseType::TAGGED === $oLast->ResponseType && \is_array($oLast->OptionalResponse)) + { + if (0 < \strlen($oLast->OptionalResponse[0]) && + 0 < \strlen($oLast->OptionalResponse[2]) && + 'APPENDUID' === strtoupper($oLast->OptionalResponse[0]) && + \is_numeric($oLast->OptionalResponse[2]) + ) + { + $iUid = (int) $oLast->OptionalResponse[2]; + } + } + } + } + + return $this; + } + + /** + * @return \MailSo\Imap\FolderInformation + */ + public function FolderCurrentInformation() + { + return $this->oCurrentFolderInfo; + } + + /** + * @param string $sCommand + * @param array $aParams = array() + * @param bool $bBreakOnLiteral = false + * + * @return string + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + */ + public function SendRequest($sCommand, $aParams = array(), $bBreakOnLiteral = false) + { + if (!\MailSo\Base\Validator::NotEmptyString($sCommand, true) || !\is_array($aParams)) + { + $this->writeLogException( + new \MailSo\Base\Exceptions\InvalidArgumentException(), + \MailSo\Log\Enumerations\Type::ERROR, true); + } + + $this->IsConnected(true); + + $sTag = $this->getNewTag(); + + $sCommand = \trim($sCommand); + $sRealCommand = $sTag.' '.$sCommand.$this->prepearParamLine($aParams); + + $sFakeCommand = ''; + $aFakeParams = $this->secureRequestParams($sCommand, $aParams); + if (null !== $aFakeParams) + { + $sFakeCommand = $sTag.' '.$sCommand.$this->prepearParamLine($aFakeParams); + } + + $this->aTagTimeouts[$sTag] = \microtime(true); + + if ($bBreakOnLiteral && !\preg_match('/\d\+\}\r\n/', $sRealCommand)) + { + $iPos = \strpos($sRealCommand, "}\r\n"); + if (false !== $iPos) + { + $iFakePos = \strpos($sFakeCommand, "}\r\n"); + + $this->sendRaw(\substr($sRealCommand, 0, $iPos + 1), true, + false !== $iFakePos ? \substr($sFakeCommand, 0, $iFakePos + 3) : ''); + + return \substr($sRealCommand, $iPos + 3); + } + } + + $this->sendRaw($sRealCommand, true, $sFakeCommand); + return ''; + } + + /** + * @param string $sCommand + * @param array $aParams + * + * @return array|null + */ + private function secureRequestParams($sCommand, $aParams) + { + $aResult = null; + switch ($sCommand) + { + case 'LOGIN': + $aResult = $aParams; + if (\is_array($aResult) && 2 === count($aResult)) + { + $aResult[1] = '"********"'; + } + break; + } + + return $aResult; + } + + /** + * @param string $sCommand + * @param array $aParams = array() + * @param bool $bFindCapa = false + * + * @return \MailSo\Imap\ImapClient + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function SendRequestWithCheck($sCommand, $aParams = array(), $bFindCapa = false) + { + $this->SendRequest($sCommand, $aParams); + $this->parseResponseWithValidation(null, $bFindCapa); + + return $this; + } + + /** + * @return array + */ + public function GetLastResponse() + { + return $this->aLastResponse; + } + + /** + * @param mixed $aResult + * + * @return array + * + * @throws \MailSo\Imap\Exceptions\ResponseNotFoundException + * @throws \MailSo\Imap\Exceptions\InvalidResponseException + * @throws \MailSo\Imap\Exceptions\NegativeResponseException + */ + private function validateResponse($aResult) + { + if (!\is_array($aResult) || 0 === $iCnt = \count($aResult)) + { + $this->writeLogException( + new Exceptions\ResponseNotFoundException(), + \MailSo\Log\Enumerations\Type::WARNING, true); + } + + if ($aResult[$iCnt - 1]->ResponseType !== \MailSo\Imap\Enumerations\ResponseType::CONTINUATION) + { + if (!$aResult[$iCnt - 1]->IsStatusResponse) + { + $this->writeLogException( + new Exceptions\InvalidResponseException($aResult), + \MailSo\Log\Enumerations\Type::WARNING, true); + } + + if (\MailSo\Imap\Enumerations\ResponseStatus::OK !== $aResult[$iCnt - 1]->StatusOrIndex) + { + $this->writeLogException( + new Exceptions\NegativeResponseException($aResult), + \MailSo\Log\Enumerations\Type::WARNING, true); + } + } + + return $aResult; + } + + /** + * @param string $sEndTag = null + * @param bool $bFindCapa = false + * + * @return array|bool + */ + protected function parseResponse($sEndTag = null, $bFindCapa = false) + { + if (\is_resource($this->rConnect)) + { + $oImapResponse = null; + $sEndTag = (null === $sEndTag) ? $this->getCurrentTag() : $sEndTag; + + while (true) + { + $oImapResponse = Response::NewInstance(); + + $this->partialParseResponseBranch($oImapResponse); + + if ($oImapResponse) + { + if (\MailSo\Imap\Enumerations\ResponseType::UNKNOWN === $oImapResponse->ResponseType) + { + return false; + } + + if ($bFindCapa) + { + $this->initCapabilityImapResponse($oImapResponse); + } + + $this->aPartialResponses[] = $oImapResponse; + if ($sEndTag === $oImapResponse->Tag || \MailSo\Imap\Enumerations\ResponseType::CONTINUATION === $oImapResponse->ResponseType) + { + if (isset($this->aTagTimeouts[$sEndTag])) + { + $this->writeLog((\microtime(true) - $this->aTagTimeouts[$sEndTag]).' ('.$sEndTag.')', + \MailSo\Log\Enumerations\Type::TIME); + + unset($this->aTagTimeouts[$sEndTag]); + } + + break; + } + } + else + { + return false; + } + + unset($oImapResponse); + } + } + + $this->iResponseBufParsedPos = 0; + $this->aLastResponse = $this->aPartialResponses; + $this->aPartialResponses = array(); + + return $this->aLastResponse; + } + + /** + * @param string $sEndTag = null + * @param bool $bFindCapa = false + * + * @return array + */ + private function parseResponseWithValidation($sEndTag = null, $bFindCapa = false) + { + return $this->validateResponse($this->parseResponse($sEndTag, $bFindCapa)); + } + + /** + * @param \MailSo\Imap\Response $oImapResponse + * + * @return void + */ + private function initCapabilityImapResponse($oImapResponse) + { + if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oImapResponse->ResponseType + && \is_array($oImapResponse->ResponseList)) + { + $aList = null; + if (isset($oImapResponse->ResponseList[1]) && \is_string($oImapResponse->ResponseList[1]) && + 'CAPABILITY' === \strtoupper($oImapResponse->ResponseList[1])) + { + $aList = \array_slice($oImapResponse->ResponseList, 2); + } + else if ($oImapResponse->OptionalResponse && \is_array($oImapResponse->OptionalResponse) && + 1 < \count($oImapResponse->OptionalResponse) && \is_string($oImapResponse->OptionalResponse[0]) && + 'CAPABILITY' === \strtoupper($oImapResponse->OptionalResponse[0])) + { + $aList = \array_slice($oImapResponse->OptionalResponse, 1); + } + + if (\is_array($aList) && 0 < \count($aList)) + { + $this->aCapabilityItems = \array_map('strtoupper', $aList); + } + } + } + + /** + * @return array|string + * + * @throws \MailSo\Net\Exceptions\Exception + */ + private function partialParseResponseBranch(&$oImapResponse, $iStackIndex = -1, + $bTreatAsAtom = false, $sParentToken = '', $sOpenBracket = '') + { + $mNull = null; + + $iStackIndex++; + $iPos = $this->iResponseBufParsedPos; + + $sPreviousAtomUpperCase = null; + $bIsEndOfList = false; + $bIsClosingBracketSquare = false; + $iLiteralLen = 0; + $iBufferEndIndex = 0; + $iDebugCount = 0; + + $rImapLiteralStream = null; + + $bIsGotoDefault = false; + $bIsGotoLiteral = false; + $bIsGotoLiteralEnd = false; + $bIsGotoAtomBracket = false; + $bIsGotoNotAtomBracket = false; + + $bCountOneInited = false; + $bCountTwoInited = false; + + $sAtomBuilder = $bTreatAsAtom ? '' : null; + $aList = array(); + if (null !== $oImapResponse) + { + $aList =& $oImapResponse->ResponseList; + } + + while (!$bIsEndOfList) + { + $iDebugCount++; + if (100000 === $iDebugCount) + { + $this->Logger()->Write('PartialParseOver: '.$iDebugCount, \MailSo\Log\Enumerations\Type::ERROR); + } + + if ($this->bNeedNext) + { + $iPos = 0; + $this->getNextBuffer(); + $this->iResponseBufParsedPos = $iPos; + $this->bNeedNext = false; + } + + $sChar = null; + if ($bIsGotoDefault) + { + $sChar = 'GOTO_DEFAULT'; + $bIsGotoDefault = false; + } + else if ($bIsGotoLiteral) + { + $bIsGotoLiteral = false; + $bIsGotoLiteralEnd = true; + + if ($this->partialResponseLiteralCallbackCallable( + $sParentToken, null === $sPreviousAtomUpperCase ? '' : \strtoupper($sPreviousAtomUpperCase), $this->rConnect, $iLiteralLen)) + { + if (!$bTreatAsAtom) + { + $aList[] = ''; + } + } + else + { + $sLiteral = ''; + $iRead = $iLiteralLen; + + while (0 < $iRead) + { + $sAddRead = \fread($this->rConnect, $iRead); + if (false === $sAddRead) + { + $sLiteral = false; + break; + } + + $sLiteral .= $sAddRead; + $iRead -= \strlen($sAddRead); + + \MailSo\Base\Utils::ResetTimeLimit(); + } + + if (false !== $sLiteral) + { + $iLiteralSize = \strlen($sLiteral); + \MailSo\Base\Loader::IncStatistic('NetRead', $iLiteralSize); + if ($iLiteralLen !== $iLiteralSize) + { + $this->writeLog('Literal stream read warning "read '.$iLiteralSize.' of '. + $iLiteralLen.'" bytes', \MailSo\Log\Enumerations\Type::WARNING); + } + + if (!$bTreatAsAtom) + { + $aList[] = $sLiteral; + + if (\MailSo\Config::$LogSimpleLiterals) + { + $this->writeLog('{'.\strlen($sLiteral).'} '.$sLiteral, \MailSo\Log\Enumerations\Type::INFO); + } + } + } + else + { + $this->writeLog('Can\'t read imap stream', \MailSo\Log\Enumerations\Type::NOTE); + } + + unset($sLiteral); + } + + continue; + } + else if ($bIsGotoLiteralEnd) + { + $rImapLiteralStream = null; + $sPreviousAtomUpperCase = null; + $this->bNeedNext = true; + $bIsGotoLiteralEnd = false; + + continue; + } + else if ($bIsGotoAtomBracket) + { + if ($bTreatAsAtom) + { + $sAtomBlock = $this->partialParseResponseBranch($mNull, $iStackIndex, true, + null === $sPreviousAtomUpperCase ? '' : \strtoupper($sPreviousAtomUpperCase), $sOpenBracket); + + $sAtomBuilder .= $sAtomBlock; + $iPos = $this->iResponseBufParsedPos; + $sAtomBuilder .= ($bIsClosingBracketSquare) ? ']' : ')'; + } + + $sPreviousAtomUpperCase = null; + $bIsGotoAtomBracket = false; + + continue; + } + else if ($bIsGotoNotAtomBracket) + { + $aSubItems = $this->partialParseResponseBranch($mNull, $iStackIndex, false, + null === $sPreviousAtomUpperCase ? '' : \strtoupper($sPreviousAtomUpperCase), $sOpenBracket); + + $aList[] = $aSubItems; + $iPos = $this->iResponseBufParsedPos; + $sPreviousAtomUpperCase = null; + if (null !== $oImapResponse && $oImapResponse->IsStatusResponse) + { + $oImapResponse->OptionalResponse = $aSubItems; + + $bIsGotoDefault = true; + $bIsGotoNotAtomBracket = false; + continue; + } + $bIsGotoNotAtomBracket = false; + + continue; + } + else + { + $iBufferEndIndex = \strlen($this->sResponseBuffer) - 3; + $this->bResponseBufferChanged = false; + + if ($iPos > $iBufferEndIndex) + { + break; + } + + $sChar = $this->sResponseBuffer[$iPos]; + } + + switch (true) + { + case ']' === $sChar: + $iPos++; + $sPreviousAtomUpperCase = null; + $bIsEndOfList = true; + break; + case ')' === $sChar: + $iPos++; + $sPreviousAtomUpperCase = null; + $bIsEndOfList = true; + break; + case ' ' === $sChar: + if ($bTreatAsAtom) + { + $sAtomBuilder .= ' '; + } + $iPos++; + break; + case '[' === $sChar: + $bIsClosingBracketSquare = true; + case '(' === $sChar: + if ('(' === $sChar) + { + $bIsClosingBracketSquare = false; + } + + if ($bTreatAsAtom) + { + $sAtomBuilder .= $bIsClosingBracketSquare ? '[' : '('; + } + $iPos++; + + $this->iResponseBufParsedPos = $iPos; + if ($bTreatAsAtom) + { + $bIsGotoAtomBracket = true; + $sOpenBracket = $bIsClosingBracketSquare ? '[' : '('; + } + else + { + $bIsGotoNotAtomBracket = true; + $sOpenBracket = $bIsClosingBracketSquare ? '[' : '('; + } + break; + case '{' === $sChar: + $bIsLiteralParsed = false; + $mLiteralEndPos = \strpos($this->sResponseBuffer, '}', $iPos); + if (false !== $mLiteralEndPos && $mLiteralEndPos > $iPos) + { + $sLiteralLenAsString = \substr($this->sResponseBuffer, $iPos + 1, $mLiteralEndPos - $iPos - 1); + if (\is_numeric($sLiteralLenAsString)) + { + $iLiteralLen = (int) $sLiteralLenAsString; + $bIsLiteralParsed = true; + $iPos = $mLiteralEndPos + 3; + $bIsGotoLiteral = true; + break; + } + } + if (!$bIsLiteralParsed) + { + $iPos = $iBufferEndIndex; + } + $sPreviousAtomUpperCase = null; + break; + case '"' === $sChar: + $bIsQuotedParsed = false; + while (true) + { + $iClosingPos = $iPos + 1; + if ($iClosingPos > $iBufferEndIndex) + { + break; + } + + while (true) + { + $iClosingPos = \strpos($this->sResponseBuffer, '"', $iClosingPos); + if (false === $iClosingPos) + { + break; + } + + // TODO + $iClosingPosNext = $iClosingPos + 1; + if ( + isset($this->sResponseBuffer[$iClosingPosNext]) && + ' ' !== $this->sResponseBuffer[$iClosingPosNext] && + "\r" !== $this->sResponseBuffer[$iClosingPosNext] && + "\n" !== $this->sResponseBuffer[$iClosingPosNext] && + ']' !== $this->sResponseBuffer[$iClosingPosNext] && + ')' !== $this->sResponseBuffer[$iClosingPosNext] + ) + { + $iClosingPos++; + continue; + } + + $iSlashCount = 0; + while ('\\' === $this->sResponseBuffer[$iClosingPos - $iSlashCount - 1]) + { + $iSlashCount++; + } + + if ($iSlashCount % 2 == 1) + { + $iClosingPos++; + continue; + } + else + { + break; + } + } + + if (false === $iClosingPos) + { + break; + } + else + { +// $iSkipClosingPos = 0; + $bIsQuotedParsed = true; + if ($bTreatAsAtom) + { + $sAtomBuilder .= \strtr( + \substr($this->sResponseBuffer, $iPos, $iClosingPos - $iPos + 1), + array('\\\\' => '\\', '\\"' => '"') + ); + } + else + { + $aList[] = \strtr( + \substr($this->sResponseBuffer, $iPos + 1, $iClosingPos - $iPos - 1), + array('\\\\' => '\\', '\\"' => '"') + ); + } + + $iPos = $iClosingPos + 1; + break; + } + } + + if (!$bIsQuotedParsed) + { + $iPos = $iBufferEndIndex; + } + + $sPreviousAtomUpperCase = null; + break; + + case 'GOTO_DEFAULT' === $sChar: + default: + $iCharBlockStartPos = $iPos; + + if (null !== $oImapResponse && $oImapResponse->IsStatusResponse) + { + $iPos = $iBufferEndIndex; + + while ($iPos > $iCharBlockStartPos && $this->sResponseBuffer[$iCharBlockStartPos] === ' ') + { + $iCharBlockStartPos++; + } + } + + $bIsAtomDone = false; + while (!$bIsAtomDone && ($iPos <= $iBufferEndIndex)) + { + $sCharDef = $this->sResponseBuffer[$iPos]; + switch (true) + { + case '[' === $sCharDef: + if (null === $sAtomBuilder) + { + $sAtomBuilder = ''; + } + + $sAtomBuilder .= \substr($this->sResponseBuffer, $iCharBlockStartPos, $iPos - $iCharBlockStartPos + 1); + + $iPos++; + $this->iResponseBufParsedPos = $iPos; + + $sListBlock = $this->partialParseResponseBranch($mNull, $iStackIndex, true, + null === $sPreviousAtomUpperCase ? '' : \strtoupper($sPreviousAtomUpperCase), '['); + + if (null !== $sListBlock) + { + $sAtomBuilder .= $sListBlock.']'; + } + + $iPos = $this->iResponseBufParsedPos; + $iCharBlockStartPos = $iPos; + break; + case ' ' === $sCharDef: + case ')' === $sCharDef && '(' === $sOpenBracket: + case ']' === $sCharDef && '[' === $sOpenBracket: + $bIsAtomDone = true; + break; + default: + $iPos++; + break; + } + } + + if ($iPos > $iCharBlockStartPos || null !== $sAtomBuilder) + { + $sLastCharBlock = \substr($this->sResponseBuffer, $iCharBlockStartPos, $iPos - $iCharBlockStartPos); + if (null === $sAtomBuilder) + { + $aList[] = $sLastCharBlock; + $sPreviousAtomUpperCase = $sLastCharBlock; + } + else + { + $sAtomBuilder .= $sLastCharBlock; + + if (!$bTreatAsAtom) + { + $aList[] = $sAtomBuilder; + $sPreviousAtomUpperCase = $sAtomBuilder; + $sAtomBuilder = null; + } + } + + if (null !== $oImapResponse) + { +// if (1 === \count($aList)) + if (!$bCountOneInited && 1 === \count($aList)) +// if (isset($aList[0]) && !isset($aList[1])) // fast 1 === \count($aList) + { + $bCountOneInited = true; + + $oImapResponse->Tag = $aList[0]; + if ('+' === $oImapResponse->Tag) + { + $oImapResponse->ResponseType = \MailSo\Imap\Enumerations\ResponseType::CONTINUATION; + } + else if ('*' === $oImapResponse->Tag) + { + $oImapResponse->ResponseType = \MailSo\Imap\Enumerations\ResponseType::UNTAGGED; + } + else if ($this->getCurrentTag() === $oImapResponse->Tag) + { + $oImapResponse->ResponseType = \MailSo\Imap\Enumerations\ResponseType::TAGGED; + } + else + { + $oImapResponse->ResponseType = \MailSo\Imap\Enumerations\ResponseType::UNKNOWN; + } + } +// else if (2 === \count($aList)) + else if (!$bCountTwoInited && 2 === \count($aList)) +// else if (isset($aList[1]) && !isset($aList[2])) // fast 2 === \count($aList) + { + $bCountTwoInited = true; + + $oImapResponse->StatusOrIndex = strtoupper($aList[1]); + + if ($oImapResponse->StatusOrIndex == \MailSo\Imap\Enumerations\ResponseStatus::OK || + $oImapResponse->StatusOrIndex == \MailSo\Imap\Enumerations\ResponseStatus::NO || + $oImapResponse->StatusOrIndex == \MailSo\Imap\Enumerations\ResponseStatus::BAD || + $oImapResponse->StatusOrIndex == \MailSo\Imap\Enumerations\ResponseStatus::BYE || + $oImapResponse->StatusOrIndex == \MailSo\Imap\Enumerations\ResponseStatus::PREAUTH) + { + $oImapResponse->IsStatusResponse = true; + } + } + else if (\MailSo\Imap\Enumerations\ResponseType::CONTINUATION === $oImapResponse->ResponseType) + { + $oImapResponse->HumanReadable = $sLastCharBlock; + } + else if ($oImapResponse->IsStatusResponse) + { + $oImapResponse->HumanReadable = $sLastCharBlock; + } + } + } + } + } + + $this->iResponseBufParsedPos = $iPos; + if (null !== $oImapResponse) + { + $this->bNeedNext = true; + $this->iResponseBufParsedPos = 0; + } + + if (100000 < $iDebugCount) + { + $this->Logger()->Write('PartialParseOverResult: '.$iDebugCount, \MailSo\Log\Enumerations\Type::ERROR); + } + + return $bTreatAsAtom ? $sAtomBuilder : $aList; + } + + /** + * @param string $sParent + * @param string $sLiteralAtomUpperCase + * @param resource $rImapStream + * @param int $iLiteralLen + * + * @return bool + */ + private function partialResponseLiteralCallbackCallable($sParent, $sLiteralAtomUpperCase, $rImapStream, $iLiteralLen) + { + $sLiteralAtomUpperCasePeek = ''; + if (0 === \strpos($sLiteralAtomUpperCase, 'BODY')) + { + $sLiteralAtomUpperCasePeek = \str_replace('BODY', 'BODY.PEEK', $sLiteralAtomUpperCase); + } + + $sFetchKey = ''; + if (\is_array($this->aFetchCallbacks)) + { + if (0 < \strlen($sLiteralAtomUpperCasePeek) && isset($this->aFetchCallbacks[$sLiteralAtomUpperCasePeek])) + { + $sFetchKey = $sLiteralAtomUpperCasePeek; + } + else if (0 < \strlen($sLiteralAtomUpperCase) && isset($this->aFetchCallbacks[$sLiteralAtomUpperCase])) + { + $sFetchKey = $sLiteralAtomUpperCase; + } + } + + $bResult = false; + if (0 < \strlen($sFetchKey) && '' !== $this->aFetchCallbacks[$sFetchKey] && + \is_callable($this->aFetchCallbacks[$sFetchKey])) + { + $rImapLiteralStream = + \MailSo\Base\StreamWrappers\Literal::CreateStream($rImapStream, $iLiteralLen); + + $bResult = true; + $this->writeLog('Start Callback for '.$sParent.' / '.$sLiteralAtomUpperCase. + ' - try to read '.$iLiteralLen.' bytes.', \MailSo\Log\Enumerations\Type::NOTE); + + $this->bRunningCallback = true; + + try + { + \call_user_func($this->aFetchCallbacks[$sFetchKey], + $sParent, $sLiteralAtomUpperCase, $rImapLiteralStream); + } + catch (\Exception $oException) + { + $this->writeLog('Callback Exception', \MailSo\Log\Enumerations\Type::NOTICE); + $this->writeLogException($oException); + } + + if (\is_resource($rImapLiteralStream)) + { + $iNotReadLiteralLen = 0; + + $bFeof = \feof($rImapLiteralStream); + $this->writeLog('End Callback for '.$sParent.' / '.$sLiteralAtomUpperCase. + ' - feof = '.($bFeof ? 'good' : 'BAD'), $bFeof ? + \MailSo\Log\Enumerations\Type::NOTE : \MailSo\Log\Enumerations\Type::WARNING); + + if (!$bFeof) + { + while (!@\feof($rImapLiteralStream)) + { + $sBuf = @\fread($rImapLiteralStream, 1024 * 1024); + if (false === $sBuf || 0 === \strlen($sBuf) || null === $sBuf) + { + break; + } + + \MailSo\Base\Utils::ResetTimeLimit(); + $iNotReadLiteralLen += \strlen($sBuf); + } + + if (\is_resource($rImapLiteralStream) && !@\feof($rImapLiteralStream)) + { + @\stream_get_contents($rImapLiteralStream); + } + } + + if (\is_resource($rImapLiteralStream)) + { + @\fclose($rImapLiteralStream); + } + + if ($iNotReadLiteralLen > 0) + { + $this->writeLog('Not read literal size is '.$iNotReadLiteralLen.' bytes.', + \MailSo\Log\Enumerations\Type::WARNING); + } + } + else + { + $this->writeLog('Literal stream is not resource after callback.', + \MailSo\Log\Enumerations\Type::WARNING); + } + + \MailSo\Base\Loader::IncStatistic('NetRead', $iLiteralLen); + + $this->bRunningCallback = false; + } + + return $bResult; + } + + /** + * @param array $aParams = null + * + * @return string + */ + private function prepearParamLine($aParams = array()) + { + $sReturn = ''; + if (\is_array($aParams) && 0 < \count($aParams)) + { + foreach ($aParams as $mParamItem) + { + if (\is_array($mParamItem) && 0 < \count($mParamItem)) + { + $sReturn .= ' ('.\trim($this->prepearParamLine($mParamItem)).')'; + } + else if (\is_string($mParamItem)) + { + $sReturn .= ' '.$mParamItem; + } + } + } + return $sReturn; + } + + /** + * @return string + */ + private function getNewTag() + { + $this->iTagCount++; + return $this->getCurrentTag(); + } + + /** + * @return string + */ + private function getCurrentTag() + { + return self::TAG_PREFIX.$this->iTagCount; + } + + /** + * @param string $sStringForEscape + * + * @return string + */ + public function EscapeString($sStringForEscape) + { + return '"'.\str_replace(array('\\', '"'), array('\\\\', '\\"'), $sStringForEscape).'"'; + } + + /** + * @return string + */ + protected function getLogName() + { + return 'IMAP'; + } + + /** + * @param \MailSo\Log\Logger $oLogger + * + * @return \MailSo\Imap\ImapClient + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + */ + public function SetLogger($oLogger) + { + parent::SetLogger($oLogger); + + return $this; + } + + /** + * @param resource $rConnect + * @param array $aCapabilityItems = array() + * + * @return \MailSo\Imap\ImapClient + */ + public function TestSetValues($rConnect, $aCapabilityItems = array()) + { + $this->rConnect = $rConnect; + $this->aCapabilityItems = $aCapabilityItems; + + return $this; + } + + /** + * @param string $sEndTag = null + * @param string $bFindCapa = false + * + * @return array + */ + public function TestParseResponseWithValidationProxy($sEndTag = null, $bFindCapa = false) + { + return $this->parseResponseWithValidation($sEndTag, $bFindCapa); + } +} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Imap/NamespaceResult.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Imap/NamespaceResult.php similarity index 95% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Imap/NamespaceResult.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Imap/NamespaceResult.php index f53bd74ff6a64460fe5b1563b85ba1701551ba05..7d053f21e77c3e2fb110ac07d643686494c9d9f9 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Imap/NamespaceResult.php +++ b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Imap/NamespaceResult.php @@ -1,132 +1,132 @@ -sPersonal = ''; - $this->sPersonalDelimiter = ''; - $this->sOtherUser = ''; - $this->sOtherUserDelimiter = ''; - $this->sShared = ''; - $this->sSharedDelimiter = ''; - } - - /** - * @return \MailSo\Imap\NamespaceResult - */ - public static function NewInstance() - { - return new self(); - } - - /** - * @param \MailSo\Imap\Response $oImapResponse - * - * @return \MailSo\Imap\NamespaceResult - */ - public function InitByImapResponse($oImapResponse) - { - if ($oImapResponse && $oImapResponse instanceof \MailSo\Imap\Response) - { - if (isset($oImapResponse->ResponseList[2][0]) && - \is_array($oImapResponse->ResponseList[2][0]) && - 2 <= \count($oImapResponse->ResponseList[2][0])) - { - $this->sPersonal = $oImapResponse->ResponseList[2][0][0]; - $this->sPersonalDelimiter = $oImapResponse->ResponseList[2][0][1]; - - $this->sPersonal = 'INBOX'.$this->sPersonalDelimiter === \substr(\strtoupper($this->sPersonal), 0, 6) ? - 'INBOX'.$this->sPersonalDelimiter.\substr($this->sPersonal, 6) : $this->sPersonal; - } - - if (isset($oImapResponse->ResponseList[3][0]) && - \is_array($oImapResponse->ResponseList[3][0]) && - 2 <= \count($oImapResponse->ResponseList[3][0])) - { - $this->sOtherUser = $oImapResponse->ResponseList[3][0][0]; - $this->sOtherUserDelimiter = $oImapResponse->ResponseList[3][0][1]; - - $this->sOtherUser = 'INBOX'.$this->sOtherUserDelimiter === \substr(\strtoupper($this->sOtherUser), 0, 6) ? - 'INBOX'.$this->sOtherUserDelimiter.\substr($this->sOtherUser, 6) : $this->sOtherUser; - } - - if (isset($oImapResponse->ResponseList[4][0]) && - \is_array($oImapResponse->ResponseList[4][0]) && - 2 <= \count($oImapResponse->ResponseList[4][0])) - { - $this->sShared = $oImapResponse->ResponseList[4][0][0]; - $this->sSharedDelimiter = $oImapResponse->ResponseList[4][0][1]; - - $this->sShared = 'INBOX'.$this->sSharedDelimiter === \substr(\strtoupper($this->sShared), 0, 6) ? - 'INBOX'.$this->sSharedDelimiter.\substr($this->sShared, 6) : $this->sShared; - } - } - - return $this; - } - - /** - * @return string - */ - public function GetPersonalNamespace() - { - return $this->sPersonal; - } - - /** - * @return string - */ - public function GetPersonalNamespaceDelimiter() - { - return $this->sPersonalDelimiter; - } -} +sPersonal = ''; + $this->sPersonalDelimiter = ''; + $this->sOtherUser = ''; + $this->sOtherUserDelimiter = ''; + $this->sShared = ''; + $this->sSharedDelimiter = ''; + } + + /** + * @return \MailSo\Imap\NamespaceResult + */ + public static function NewInstance() + { + return new self(); + } + + /** + * @param \MailSo\Imap\Response $oImapResponse + * + * @return \MailSo\Imap\NamespaceResult + */ + public function InitByImapResponse($oImapResponse) + { + if ($oImapResponse && $oImapResponse instanceof \MailSo\Imap\Response) + { + if (isset($oImapResponse->ResponseList[2][0]) && + \is_array($oImapResponse->ResponseList[2][0]) && + 2 <= \count($oImapResponse->ResponseList[2][0])) + { + $this->sPersonal = $oImapResponse->ResponseList[2][0][0]; + $this->sPersonalDelimiter = $oImapResponse->ResponseList[2][0][1]; + + $this->sPersonal = 'INBOX'.$this->sPersonalDelimiter === \substr(\strtoupper($this->sPersonal), 0, 6) ? + 'INBOX'.$this->sPersonalDelimiter.\substr($this->sPersonal, 6) : $this->sPersonal; + } + + if (isset($oImapResponse->ResponseList[3][0]) && + \is_array($oImapResponse->ResponseList[3][0]) && + 2 <= \count($oImapResponse->ResponseList[3][0])) + { + $this->sOtherUser = $oImapResponse->ResponseList[3][0][0]; + $this->sOtherUserDelimiter = $oImapResponse->ResponseList[3][0][1]; + + $this->sOtherUser = 'INBOX'.$this->sOtherUserDelimiter === \substr(\strtoupper($this->sOtherUser), 0, 6) ? + 'INBOX'.$this->sOtherUserDelimiter.\substr($this->sOtherUser, 6) : $this->sOtherUser; + } + + if (isset($oImapResponse->ResponseList[4][0]) && + \is_array($oImapResponse->ResponseList[4][0]) && + 2 <= \count($oImapResponse->ResponseList[4][0])) + { + $this->sShared = $oImapResponse->ResponseList[4][0][0]; + $this->sSharedDelimiter = $oImapResponse->ResponseList[4][0][1]; + + $this->sShared = 'INBOX'.$this->sSharedDelimiter === \substr(\strtoupper($this->sShared), 0, 6) ? + 'INBOX'.$this->sSharedDelimiter.\substr($this->sShared, 6) : $this->sShared; + } + } + + return $this; + } + + /** + * @return string + */ + public function GetPersonalNamespace() + { + return $this->sPersonal; + } + + /** + * @return string + */ + public function GetPersonalNamespaceDelimiter() + { + return $this->sPersonalDelimiter; + } +} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Imap/Response.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Imap/Response.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Imap/Response.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Imap/Response.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/LICENSE b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/LICENSE similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/LICENSE rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/LICENSE diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Log/Driver.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Log/Driver.php similarity index 95% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Log/Driver.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Log/Driver.php index 457b78c47c04c7647910a91f3c4ade49d577f95c..fd313fc2821ada387e555993f5cae1cf0480058a 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Log/Driver.php +++ b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Log/Driver.php @@ -1,408 +1,408 @@ -sDatePattern = 'H:i:s'; - $this->sName = 'INFO'; - $this->sNewLine = "\r\n"; - $this->bTimePrefix = true; - $this->bTypedPrefix = true; - $this->bGuidPrefix = true; - - $this->sTimeOffset = '0'; - - $this->iWriteOnTimeoutOnly = 0; - $this->bWriteOnErrorOnly = false; - $this->bWriteOnPhpErrorOnly = false; - $this->bFlushCache = false; - $this->aCache = array(); - - $this->aPrefixes = array( - \MailSo\Log\Enumerations\Type::INFO => '[DATA]', - \MailSo\Log\Enumerations\Type::SECURE => '[SECURE]', - \MailSo\Log\Enumerations\Type::NOTE => '[NOTE]', - \MailSo\Log\Enumerations\Type::TIME => '[TIME]', - \MailSo\Log\Enumerations\Type::TIME_DELTA => '[TIME]', - \MailSo\Log\Enumerations\Type::MEMORY => '[MEMORY]', - \MailSo\Log\Enumerations\Type::NOTICE => '[NOTICE]', - \MailSo\Log\Enumerations\Type::WARNING => '[WARNING]', - \MailSo\Log\Enumerations\Type::ERROR => '[ERROR]', - - \MailSo\Log\Enumerations\Type::NOTICE_PHP => '[NOTICE]', - \MailSo\Log\Enumerations\Type::WARNING_PHP => '[WARNING]', - \MailSo\Log\Enumerations\Type::ERROR_PHP => '[ERROR]', - ); - } - - /** - * @param string $sTimeOffset - * - * @return \MailSo\Log\Driver - */ - public function SetTimeOffset($sTimeOffset) - { - $this->sTimeOffset = (string) $sTimeOffset; - return $this; - } - - /** - * @return \MailSo\Log\Driver - */ - public function DisableGuidPrefix() - { - $this->bGuidPrefix = false; - return $this; - } - - /** - * @return \MailSo\Log\Driver - */ - public function DisableTimePrefix() - { - $this->bTimePrefix = false; - return $this; - } - - /** - * @param bool $bValue - * - * @return \MailSo\Log\Driver - */ - public function WriteOnErrorOnly($bValue) - { - $this->bWriteOnErrorOnly = !!$bValue; - return $this; - } - - /** - * @param bool $bValue - * - * @return \MailSo\Log\Driver - */ - public function WriteOnPhpErrorOnly($bValue) - { - $this->bWriteOnPhpErrorOnly = !!$bValue; - return $this; - } - - /** - * @param int $iTimeout - * - * @return \MailSo\Log\Driver - */ - public function WriteOnTimeoutOnly($iTimeout) - { - $this->iWriteOnTimeoutOnly = (int) $iTimeout; - if (0 > $this->iWriteOnTimeoutOnly) - { - $this->iWriteOnTimeoutOnly = 0; - } - - return $this; - } - - /** - * @return \MailSo\Log\Driver - */ - public function DisableTypedPrefix() - { - $this->bTypedPrefix = false; - return $this; - } - - /** - * @param string|array $mDesc - * @return bool - */ - abstract protected function writeImplementation($mDesc); - - /** - * @return bool - */ - protected function writeEmptyLineImplementation() - { - return $this->writeImplementation(''); - } - - /** - * @param string $sTimePrefix - * @param string $sDesc - * @param int $iType = \MailSo\Log\Enumerations\Type::INFO - * @param array $sName = '' - * - * @return string - */ - protected function loggerLineImplementation($sTimePrefix, $sDesc, - $iType = \MailSo\Log\Enumerations\Type::INFO, $sName = '') - { - return \ltrim( - ($this->bTimePrefix ? '['.$sTimePrefix.']' : ''). - ($this->bGuidPrefix ? '['.\MailSo\Log\Logger::Guid().']' : ''). - ($this->bTypedPrefix ? ' '.$this->getTypedPrefix($iType, $sName) : '') - ).$sDesc; - } - - /** - * @return bool - */ - protected function clearImplementation() - { - return true; - } - - /** - * @return string - */ - protected function getTimeWithMicroSec() - { - $aMicroTimeItems = \explode(' ', \microtime()); - return \MailSo\Log\Logger::DateHelper($this->sDatePattern, $this->sTimeOffset, $aMicroTimeItems[1]).'.'. - \str_pad((int) ($aMicroTimeItems[0] * 1000), 3, '0', STR_PAD_LEFT); - } - - /** - * @param int $iType - * @param string $sName = '' - * - * @return string - */ - protected function getTypedPrefix($iType, $sName = '') - { - $sName = 0 < \strlen($sName) ? $sName : $this->sName; - return isset($this->aPrefixes[$iType]) ? $sName.$this->aPrefixes[$iType].': ' : ''; - } - - /** - * @param string|array $mDesc - * @param bool $bDiplayCrLf = false - * - * @return string - */ - protected function localWriteImplementation($mDesc, $bDiplayCrLf = false) - { - if ($bDiplayCrLf) - { - if (\is_array($mDesc)) - { - foreach ($mDesc as &$sLine) - { - $sLine = \strtr($sLine, array("\r" => '\r', "\n" => '\n'.$this->sNewLine)); - $sLine = \rtrim($sLine); - } - } - else - { - $mDesc = \strtr($mDesc, array("\r" => '\r', "\n" => '\n'.$this->sNewLine)); - $mDesc = \rtrim($mDesc); - } - } - - return $this->writeImplementation($mDesc); - } - - /** - * @final - * @param string $sDesc - * @param int $iType = \MailSo\Log\Enumerations\Type::INFO - * @param string $sName = '' - * @param bool $bDiplayCrLf = false - * - * @return bool - */ - final public function Write($sDesc, $iType = \MailSo\Log\Enumerations\Type::INFO, $sName = '', $bDiplayCrLf = false) - { - $bResult = true; - if (!$this->bFlushCache && ($this->bWriteOnErrorOnly || $this->bWriteOnPhpErrorOnly || 0 < $this->iWriteOnTimeoutOnly)) - { - $bErrorPhp = false; - - $bError = $this->bWriteOnErrorOnly && \in_array($iType, array( - \MailSo\Log\Enumerations\Type::NOTICE, - \MailSo\Log\Enumerations\Type::NOTICE_PHP, - \MailSo\Log\Enumerations\Type::WARNING, - \MailSo\Log\Enumerations\Type::WARNING_PHP, - \MailSo\Log\Enumerations\Type::ERROR, - \MailSo\Log\Enumerations\Type::ERROR_PHP - )); - - if (!$bError) - { - $bErrorPhp = $this->bWriteOnPhpErrorOnly && \in_array($iType, array( - \MailSo\Log\Enumerations\Type::NOTICE_PHP, - \MailSo\Log\Enumerations\Type::WARNING_PHP, - \MailSo\Log\Enumerations\Type::ERROR_PHP - )); - } - - if ($bError || $bErrorPhp) - { - $sFlush = '--- FlushLogCache: '.($bError ? 'WriteOnErrorOnly' : 'WriteOnPhpErrorOnly'); - if (isset($this->aCache[0]) && empty($this->aCache[0])) - { - $this->aCache[0] = $sFlush; - \array_unshift($this->aCache, ''); - } - else - { - \array_unshift($this->aCache, $sFlush); - } - - $this->aCache[] = '--- FlushLogCache: Trigger'; - $this->aCache[] = $this->loggerLineImplementation($this->getTimeWithMicroSec(), $sDesc, $iType, $sName); - - $this->bFlushCache = true; - $bResult = $this->localWriteImplementation($this->aCache, $bDiplayCrLf); - $this->aCache = array(); - } - else if (0 < $this->iWriteOnTimeoutOnly && \time() - APP_START_TIME > $this->iWriteOnTimeoutOnly) - { - $sFlush = '--- FlushLogCache: WriteOnTimeoutOnly ['.(\time() - APP_START_TIME).'sec]'; - if (isset($this->aCache[0]) && empty($this->aCache[0])) - { - $this->aCache[0] = $sFlush; - \array_unshift($this->aCache, ''); - } - else - { - \array_unshift($this->aCache, $sFlush); - } - - $this->aCache[] = '--- FlushLogCache: Trigger'; - $this->aCache[] = $this->loggerLineImplementation($this->getTimeWithMicroSec(), $sDesc, $iType, $sName); - - $this->bFlushCache = true; - $bResult = $this->localWriteImplementation($this->aCache, $bDiplayCrLf); - $this->aCache = array(); - } - else - { - $this->aCache[] = $this->loggerLineImplementation($this->getTimeWithMicroSec(), $sDesc, $iType, $sName); - } - } - else - { - $bResult = $this->localWriteImplementation( - $this->loggerLineImplementation($this->getTimeWithMicroSec(), $sDesc, $iType, $sName), $bDiplayCrLf); - } - - return $bResult; - } - - /** - * @return string - */ - public function GetNewLine() - { - return $this->sNewLine; - } - - /** - * @final - * @return bool - */ - final public function Clear() - { - return $this->clearImplementation(); - } - - /** - * @final - * @return void - */ - final public function WriteEmptyLine() - { - if (!$this->bFlushCache && ($this->bWriteOnErrorOnly || $this->bWriteOnPhpErrorOnly || 0 < $this->iWriteOnTimeoutOnly)) - { - $this->aCache[] = ''; - } - else - { - $this->writeEmptyLineImplementation(); - } - } -} +sDatePattern = 'H:i:s'; + $this->sName = 'INFO'; + $this->sNewLine = "\r\n"; + $this->bTimePrefix = true; + $this->bTypedPrefix = true; + $this->bGuidPrefix = true; + + $this->sTimeOffset = '0'; + + $this->iWriteOnTimeoutOnly = 0; + $this->bWriteOnErrorOnly = false; + $this->bWriteOnPhpErrorOnly = false; + $this->bFlushCache = false; + $this->aCache = array(); + + $this->aPrefixes = array( + \MailSo\Log\Enumerations\Type::INFO => '[DATA]', + \MailSo\Log\Enumerations\Type::SECURE => '[SECURE]', + \MailSo\Log\Enumerations\Type::NOTE => '[NOTE]', + \MailSo\Log\Enumerations\Type::TIME => '[TIME]', + \MailSo\Log\Enumerations\Type::TIME_DELTA => '[TIME]', + \MailSo\Log\Enumerations\Type::MEMORY => '[MEMORY]', + \MailSo\Log\Enumerations\Type::NOTICE => '[NOTICE]', + \MailSo\Log\Enumerations\Type::WARNING => '[WARNING]', + \MailSo\Log\Enumerations\Type::ERROR => '[ERROR]', + + \MailSo\Log\Enumerations\Type::NOTICE_PHP => '[NOTICE]', + \MailSo\Log\Enumerations\Type::WARNING_PHP => '[WARNING]', + \MailSo\Log\Enumerations\Type::ERROR_PHP => '[ERROR]', + ); + } + + /** + * @param string $sTimeOffset + * + * @return \MailSo\Log\Driver + */ + public function SetTimeOffset($sTimeOffset) + { + $this->sTimeOffset = (string) $sTimeOffset; + return $this; + } + + /** + * @return \MailSo\Log\Driver + */ + public function DisableGuidPrefix() + { + $this->bGuidPrefix = false; + return $this; + } + + /** + * @return \MailSo\Log\Driver + */ + public function DisableTimePrefix() + { + $this->bTimePrefix = false; + return $this; + } + + /** + * @param bool $bValue + * + * @return \MailSo\Log\Driver + */ + public function WriteOnErrorOnly($bValue) + { + $this->bWriteOnErrorOnly = !!$bValue; + return $this; + } + + /** + * @param bool $bValue + * + * @return \MailSo\Log\Driver + */ + public function WriteOnPhpErrorOnly($bValue) + { + $this->bWriteOnPhpErrorOnly = !!$bValue; + return $this; + } + + /** + * @param int $iTimeout + * + * @return \MailSo\Log\Driver + */ + public function WriteOnTimeoutOnly($iTimeout) + { + $this->iWriteOnTimeoutOnly = (int) $iTimeout; + if (0 > $this->iWriteOnTimeoutOnly) + { + $this->iWriteOnTimeoutOnly = 0; + } + + return $this; + } + + /** + * @return \MailSo\Log\Driver + */ + public function DisableTypedPrefix() + { + $this->bTypedPrefix = false; + return $this; + } + + /** + * @param string|array $mDesc + * @return bool + */ + abstract protected function writeImplementation($mDesc); + + /** + * @return bool + */ + protected function writeEmptyLineImplementation() + { + return $this->writeImplementation(''); + } + + /** + * @param string $sTimePrefix + * @param string $sDesc + * @param int $iType = \MailSo\Log\Enumerations\Type::INFO + * @param array $sName = '' + * + * @return string + */ + protected function loggerLineImplementation($sTimePrefix, $sDesc, + $iType = \MailSo\Log\Enumerations\Type::INFO, $sName = '') + { + return \ltrim( + ($this->bTimePrefix ? '['.$sTimePrefix.']' : ''). + ($this->bGuidPrefix ? '['.\MailSo\Log\Logger::Guid().']' : ''). + ($this->bTypedPrefix ? ' '.$this->getTypedPrefix($iType, $sName) : '') + ).$sDesc; + } + + /** + * @return bool + */ + protected function clearImplementation() + { + return true; + } + + /** + * @return string + */ + protected function getTimeWithMicroSec() + { + $aMicroTimeItems = \explode(' ', \microtime()); + return \MailSo\Log\Logger::DateHelper($this->sDatePattern, $this->sTimeOffset, $aMicroTimeItems[1]).'.'. + \str_pad((int) ($aMicroTimeItems[0] * 1000), 3, '0', STR_PAD_LEFT); + } + + /** + * @param int $iType + * @param string $sName = '' + * + * @return string + */ + protected function getTypedPrefix($iType, $sName = '') + { + $sName = 0 < \strlen($sName) ? $sName : $this->sName; + return isset($this->aPrefixes[$iType]) ? $sName.$this->aPrefixes[$iType].': ' : ''; + } + + /** + * @param string|array $mDesc + * @param bool $bDiplayCrLf = false + * + * @return string + */ + protected function localWriteImplementation($mDesc, $bDiplayCrLf = false) + { + if ($bDiplayCrLf) + { + if (\is_array($mDesc)) + { + foreach ($mDesc as &$sLine) + { + $sLine = \strtr($sLine, array("\r" => '\r', "\n" => '\n'.$this->sNewLine)); + $sLine = \rtrim($sLine); + } + } + else + { + $mDesc = \strtr($mDesc, array("\r" => '\r', "\n" => '\n'.$this->sNewLine)); + $mDesc = \rtrim($mDesc); + } + } + + return $this->writeImplementation($mDesc); + } + + /** + * @final + * @param string $sDesc + * @param int $iType = \MailSo\Log\Enumerations\Type::INFO + * @param string $sName = '' + * @param bool $bDiplayCrLf = false + * + * @return bool + */ + final public function Write($sDesc, $iType = \MailSo\Log\Enumerations\Type::INFO, $sName = '', $bDiplayCrLf = false) + { + $bResult = true; + if (!$this->bFlushCache && ($this->bWriteOnErrorOnly || $this->bWriteOnPhpErrorOnly || 0 < $this->iWriteOnTimeoutOnly)) + { + $bErrorPhp = false; + + $bError = $this->bWriteOnErrorOnly && \in_array($iType, array( + \MailSo\Log\Enumerations\Type::NOTICE, + \MailSo\Log\Enumerations\Type::NOTICE_PHP, + \MailSo\Log\Enumerations\Type::WARNING, + \MailSo\Log\Enumerations\Type::WARNING_PHP, + \MailSo\Log\Enumerations\Type::ERROR, + \MailSo\Log\Enumerations\Type::ERROR_PHP + )); + + if (!$bError) + { + $bErrorPhp = $this->bWriteOnPhpErrorOnly && \in_array($iType, array( + \MailSo\Log\Enumerations\Type::NOTICE_PHP, + \MailSo\Log\Enumerations\Type::WARNING_PHP, + \MailSo\Log\Enumerations\Type::ERROR_PHP + )); + } + + if ($bError || $bErrorPhp) + { + $sFlush = '--- FlushLogCache: '.($bError ? 'WriteOnErrorOnly' : 'WriteOnPhpErrorOnly'); + if (isset($this->aCache[0]) && empty($this->aCache[0])) + { + $this->aCache[0] = $sFlush; + \array_unshift($this->aCache, ''); + } + else + { + \array_unshift($this->aCache, $sFlush); + } + + $this->aCache[] = '--- FlushLogCache: Trigger'; + $this->aCache[] = $this->loggerLineImplementation($this->getTimeWithMicroSec(), $sDesc, $iType, $sName); + + $this->bFlushCache = true; + $bResult = $this->localWriteImplementation($this->aCache, $bDiplayCrLf); + $this->aCache = array(); + } + else if (0 < $this->iWriteOnTimeoutOnly && \time() - APP_START_TIME > $this->iWriteOnTimeoutOnly) + { + $sFlush = '--- FlushLogCache: WriteOnTimeoutOnly ['.(\time() - APP_START_TIME).'sec]'; + if (isset($this->aCache[0]) && empty($this->aCache[0])) + { + $this->aCache[0] = $sFlush; + \array_unshift($this->aCache, ''); + } + else + { + \array_unshift($this->aCache, $sFlush); + } + + $this->aCache[] = '--- FlushLogCache: Trigger'; + $this->aCache[] = $this->loggerLineImplementation($this->getTimeWithMicroSec(), $sDesc, $iType, $sName); + + $this->bFlushCache = true; + $bResult = $this->localWriteImplementation($this->aCache, $bDiplayCrLf); + $this->aCache = array(); + } + else + { + $this->aCache[] = $this->loggerLineImplementation($this->getTimeWithMicroSec(), $sDesc, $iType, $sName); + } + } + else + { + $bResult = $this->localWriteImplementation( + $this->loggerLineImplementation($this->getTimeWithMicroSec(), $sDesc, $iType, $sName), $bDiplayCrLf); + } + + return $bResult; + } + + /** + * @return string + */ + public function GetNewLine() + { + return $this->sNewLine; + } + + /** + * @final + * @return bool + */ + final public function Clear() + { + return $this->clearImplementation(); + } + + /** + * @final + * @return void + */ + final public function WriteEmptyLine() + { + if (!$this->bFlushCache && ($this->bWriteOnErrorOnly || $this->bWriteOnPhpErrorOnly || 0 < $this->iWriteOnTimeoutOnly)) + { + $this->aCache[] = ''; + } + else + { + $this->writeEmptyLineImplementation(); + } + } +} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Log/Drivers/Callback.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Log/Drivers/Callback.php similarity index 94% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Log/Drivers/Callback.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Log/Drivers/Callback.php index 021d7e82b0409ed5f19643338f5172e047aa5556..46e8789334536f719f3206dc82324644512531c2 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Log/Drivers/Callback.php +++ b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Log/Drivers/Callback.php @@ -1,83 +1,83 @@ -fWriteCallback = \is_callable($fWriteCallback) ? $fWriteCallback : null; - $this->fClearCallback = \is_callable($fClearCallback) ? $fClearCallback : null; - } - - /** - * @param mixed $fWriteCallback - * @param mixed $fClearCallback = null - * - * @return \MailSo\Log\Drivers\Callback - */ - public static function NewInstance($fWriteCallback, $fClearCallback = null) - { - return new self($fWriteCallback, $fClearCallback); - } - - /** - * @param string|array $mDesc - * - * @return bool - */ - protected function writeImplementation($mDesc) - { - if ($this->fWriteCallback) - { - \call_user_func_array($this->fWriteCallback, array($mDesc)); - } - - return true; - } - - /** - * @return bool - */ - protected function clearImplementation() - { - if ($this->fClearCallback) - { - \call_user_func($this->fClearCallback); - } - - return true; - } -} +fWriteCallback = \is_callable($fWriteCallback) ? $fWriteCallback : null; + $this->fClearCallback = \is_callable($fClearCallback) ? $fClearCallback : null; + } + + /** + * @param mixed $fWriteCallback + * @param mixed $fClearCallback = null + * + * @return \MailSo\Log\Drivers\Callback + */ + public static function NewInstance($fWriteCallback, $fClearCallback = null) + { + return new self($fWriteCallback, $fClearCallback); + } + + /** + * @param string|array $mDesc + * + * @return bool + */ + protected function writeImplementation($mDesc) + { + if ($this->fWriteCallback) + { + \call_user_func_array($this->fWriteCallback, array($mDesc)); + } + + return true; + } + + /** + * @return bool + */ + protected function clearImplementation() + { + if ($this->fClearCallback) + { + \call_user_func($this->fClearCallback); + } + + return true; + } +} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Log/Drivers/File.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Log/Drivers/File.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Log/Drivers/File.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Log/Drivers/File.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Log/Drivers/Inline.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Log/Drivers/Inline.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Log/Drivers/Inline.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Log/Drivers/Inline.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Log/Drivers/Syslog.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Log/Drivers/Syslog.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Log/Drivers/Syslog.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Log/Drivers/Syslog.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Log/Enumerations/Type.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Log/Enumerations/Type.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Log/Enumerations/Type.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Log/Enumerations/Type.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Log/Logger.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Log/Logger.php similarity index 95% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Log/Logger.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Log/Logger.php index cb5dea68cdf06480cf115dce7be2a6080de7ee67..82cbf5418961c0de4f64a06dd318e43425df631c 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Log/Logger.php +++ b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Log/Logger.php @@ -1,431 +1,431 @@ -bUsed = false; - $this->aForbiddenTypes = array(); - $this->aSecretWords = array(); - $this->bShowSecter = false; - $this->bHideErrorNotices = false; - - if ($bRegPhpErrorHandler) - { - \set_error_handler(array(&$this, '__phpErrorHandler')); - } - - \register_shutdown_function(array(&$this, '__loggerShutDown')); - } - - /** - * @param bool $bRegPhpErrorHandler = false - * - * @return \MailSo\Log\Logger - */ - public static function NewInstance($bRegPhpErrorHandler = false) - { - return new self($bRegPhpErrorHandler); - } - - /** - * @staticvar \MailSo\Log\Logger $oInstance; - * - * @return \MailSo\Log\Logger - */ - public static function SingletonInstance() - { - static $oInstance = null; - if (null === $oInstance) - { - $oInstance = self::NewInstance(); - } - - return $oInstance; - } - - /** - * @param string $sFormat - * @param string $sTimeOffset = '0' - * @param int $iTimestamp = 0 - * - * @return string - */ - public static function DateHelper($sFormat, $sTimeOffset = '0', $iTimestamp = null) - { - $iTimestamp = null === $iTimestamp ? \time() : (int) $iTimestamp; - return \gmdate($sFormat, $iTimestamp + \MailSo\Base\DateTimeHelper::TimeToSec((string) $sTimeOffset)); - } - - /** - * @return bool - */ - public static function IsSystemEnabled() - { - return !!(\MailSo\Config::$SystemLogger instanceof \MailSo\Log\Logger); - } - - /** - * @param mixed $mData - * @param int $iType = \MailSo\Log\Enumerations\Type::INFO - */ - public static function SystemLog($mData, $iType = \MailSo\Log\Enumerations\Type::INFO) - { - if (\MailSo\Config::$SystemLogger instanceof \MailSo\Log\Logger) - { - \MailSo\Config::$SystemLogger->WriteMixed($mData, $iType); - } - } - - /** - * @staticvar string $sCache; - * - * @return string - */ - public static function Guid() - { - static $sCache = null; - if (null === $sCache) - { - $sCache = \substr(\MailSo\Base\Utils::Md5Rand(), -8); - } - - return $sCache; - } - - /** - * @return bool - */ - public function Ping() - { - return true; - } - - /** - * @return bool - */ - public function IsEnabled() - { - return 0 < $this->Count(); - } - - /** - * @param string $sWord - * - * @return bool - */ - public function AddSecret($sWord) - { - if (\is_string($sWord) && 0 < \strlen(\trim($sWord))) - { - $this->aSecretWords[] = $sWord; - $this->aSecretWords = \array_unique($this->aSecretWords); - } - } - - /** - * @param bool $bShow - * - * @return \MailSo\Log\Logger - */ - public function SetShowSecter($bShow) - { - $this->bShowSecter = !!$bShow; - return $this; - } - - /** - * @param bool $bValue - * - * @return \MailSo\Log\Logger - */ - public function HideErrorNotices($bValue) - { - $this->bHideErrorNotices = !!$bValue; - return $this; - } - - /** - * @return bool - */ - public function IsShowSecter() - { - return $this->bShowSecter; - } - - /** - * @param int $iType - * - * @return \MailSo\Log\Logger - */ - public function AddForbiddenType($iType) - { - $this->aForbiddenTypes[$iType] = true; - - return $this; - } - - /** - * @param int $iType - * - * @return \MailSo\Log\Logger - */ - public function RemoveForbiddenType($iType) - { - $this->aForbiddenTypes[$iType] = false; - return $this; - } - - /** - * @param int $iErrNo - * @param string $sErrStr - * @param string $sErrFile - * @param int $iErrLine - * - * @return bool - */ - public function __phpErrorHandler($iErrNo, $sErrStr, $sErrFile, $iErrLine) - { - $iType = \MailSo\Log\Enumerations\Type::NOTICE_PHP; - switch ($iErrNo) - { - case E_USER_ERROR: - $iType = \MailSo\Log\Enumerations\Type::ERROR_PHP; - break; - case E_USER_WARNING: - $iType = \MailSo\Log\Enumerations\Type::WARNING_PHP; - break; - } - - $this->Write($sErrFile.' [line:'.$iErrLine.', code:'.$iErrNo.']', $iType, 'PHP'); - $this->Write('Error: '.$sErrStr, $iType, 'PHP'); - - return !!(\MailSo\Log\Enumerations\Type::NOTICE === $iType && $this->bHideErrorNotices); - } - - /** - * @return void - */ - public function __loggerShutDown() - { - if ($this->bUsed) - { - $aStatistic = \MailSo\Base\Loader::Statistic(); - if (\is_array($aStatistic)) - { - if (isset($aStatistic['php']['memory_get_peak_usage'])) - { - $this->Write('Memory peak usage: '.$aStatistic['php']['memory_get_peak_usage'], - \MailSo\Log\Enumerations\Type::MEMORY); - } - - if (isset($aStatistic['time'])) - { - $this->Write('Time delta: '.$aStatistic['time'], \MailSo\Log\Enumerations\Type::TIME_DELTA); - } - } - } - } - - /** - * @return bool - */ - public function WriteEmptyLine() - { - $iResult = 1; - - $aLoggers =& $this->GetAsArray(); - foreach ($aLoggers as /* @var $oLogger \MailSo\Log\Driver */ &$oLogger) - { - $iResult &= $oLogger->WriteEmptyLine(); - } - - return (bool) $iResult; - } - - /** - * @param string $sDesc - * @param int $iType = \MailSo\Log\Enumerations\Type::INFO - * @param string $sName = '' - * @param bool $bSearchSecretWords = true - * @param bool $bDiplayCrLf = false - * - * @return bool - */ - public function Write($sDesc, $iType = \MailSo\Log\Enumerations\Type::INFO, - $sName = '', $bSearchSecretWords = true, $bDiplayCrLf = false) - { - if (isset($this->aForbiddenTypes[$iType]) && true === $this->aForbiddenTypes[$iType]) - { - return true; - } - - $this->bUsed = true; - - $oLogger = null; - $aLoggers = array(); - $iResult = 1; - - if ($bSearchSecretWords && !$this->bShowSecter && 0 < \count($this->aSecretWords)) - { - $sDesc = \str_replace($this->aSecretWords, '*******', $sDesc); - } - - $aLoggers =& $this->GetAsArray(); - foreach ($aLoggers as /* @var $oLogger \MailSo\Log\Driver */ $oLogger) - { - $iResult &= $oLogger->Write($sDesc, $iType, $sName, $bDiplayCrLf); - } - - return (bool) $iResult; - } - - /** - * @param mixed $oValue - * @param int $iType = \MailSo\Log\Enumerations\Type::INFO - * @param string $sName = '' - * @param bool $bSearchSecretWords = false - * @param bool $bDiplayCrLf = false - * - * @return bool - */ - public function WriteDump($oValue, $iType = \MailSo\Log\Enumerations\Type::INFO, $sName = '', - $bSearchSecretWords = false, $bDiplayCrLf = false) - { - return $this->Write(\print_r($oValue, true), $iType, $sName, $bSearchSecretWords, $bDiplayCrLf); - } - - /** - * @param \Exception $oException - * @param int $iType = \MailSo\Log\Enumerations\Type::NOTICE - * @param string $sName = '' - * @param bool $bSearchSecretWords = true - * @param bool $bDiplayCrLf = false - * - * @return bool - */ - public function WriteException($oException, $iType = \MailSo\Log\Enumerations\Type::NOTICE, $sName = '', - $bSearchSecretWords = true, $bDiplayCrLf = false) - { - if ($oException instanceof \Exception) - { - if (isset($oException->__LOGINNED__)) - { - return true; - } - - $oException->__LOGINNED__ = true; - - return $this->Write((string) $oException, $iType, $sName, $bSearchSecretWords, $bDiplayCrLf); - } - - return false; - } - - /** - * @param \Exception $oException - * @param int $iType = \MailSo\Log\Enumerations\Type::NOTICE - * @param string $sName = '' - * @param bool $bSearchSecretWords = true - * @param bool $bDiplayCrLf = false - * - * @return bool - */ - public function WriteExceptionShort($oException, $iType = \MailSo\Log\Enumerations\Type::NOTICE, $sName = '', - $bSearchSecretWords = true, $bDiplayCrLf = false) - { - if ($oException instanceof \Exception) - { - if (isset($oException->__LOGINNED__)) - { - return true; - } - - $oException->__LOGINNED__ = true; - - return $this->Write($oException->getMessage(), $iType, $sName, $bSearchSecretWords, $bDiplayCrLf); - } - - return false; - } - - /** - * @param mixed $mData - * @param int $iType = \MailSo\Log\Enumerations\Type::NOTICE - * @param string $sName = '' - * @param bool $bSearchSecretWords = true - * @param bool $bDiplayCrLf = false - * - * @return bool - */ - public function WriteMixed($mData, $iType = null, $sName = '', - $bSearchSecretWords = true, $bDiplayCrLf = false) - { - $iType = null === $iType ? \MailSo\Log\Enumerations\Type::INFO : $iType; - if (\is_array($mData) || \is_object($mData)) - { - if ($mData instanceof \Exception) - { - $iType = null === $iType ? \MailSo\Log\Enumerations\Type::NOTICE : $iType; - return $this->WriteException($mData, $iType, $sName, $bSearchSecretWords, $bDiplayCrLf); - } - else - { - return $this->WriteDump($mData, $iType, $sName, $bSearchSecretWords, $bDiplayCrLf); - } - } - else - { - return $this->Write($mData, $iType, $sName, $bSearchSecretWords, $bDiplayCrLf); - } - - return false; - } -} +bUsed = false; + $this->aForbiddenTypes = array(); + $this->aSecretWords = array(); + $this->bShowSecter = false; + $this->bHideErrorNotices = false; + + if ($bRegPhpErrorHandler) + { + \set_error_handler(array(&$this, '__phpErrorHandler')); + } + + \register_shutdown_function(array(&$this, '__loggerShutDown')); + } + + /** + * @param bool $bRegPhpErrorHandler = false + * + * @return \MailSo\Log\Logger + */ + public static function NewInstance($bRegPhpErrorHandler = false) + { + return new self($bRegPhpErrorHandler); + } + + /** + * @staticvar \MailSo\Log\Logger $oInstance; + * + * @return \MailSo\Log\Logger + */ + public static function SingletonInstance() + { + static $oInstance = null; + if (null === $oInstance) + { + $oInstance = self::NewInstance(); + } + + return $oInstance; + } + + /** + * @param string $sFormat + * @param string $sTimeOffset = '0' + * @param int $iTimestamp = 0 + * + * @return string + */ + public static function DateHelper($sFormat, $sTimeOffset = '0', $iTimestamp = null) + { + $iTimestamp = null === $iTimestamp ? \time() : (int) $iTimestamp; + return \gmdate($sFormat, $iTimestamp + \MailSo\Base\DateTimeHelper::TimeToSec((string) $sTimeOffset)); + } + + /** + * @return bool + */ + public static function IsSystemEnabled() + { + return !!(\MailSo\Config::$SystemLogger instanceof \MailSo\Log\Logger); + } + + /** + * @param mixed $mData + * @param int $iType = \MailSo\Log\Enumerations\Type::INFO + */ + public static function SystemLog($mData, $iType = \MailSo\Log\Enumerations\Type::INFO) + { + if (\MailSo\Config::$SystemLogger instanceof \MailSo\Log\Logger) + { + \MailSo\Config::$SystemLogger->WriteMixed($mData, $iType); + } + } + + /** + * @staticvar string $sCache; + * + * @return string + */ + public static function Guid() + { + static $sCache = null; + if (null === $sCache) + { + $sCache = \substr(\MailSo\Base\Utils::Md5Rand(), -8); + } + + return $sCache; + } + + /** + * @return bool + */ + public function Ping() + { + return true; + } + + /** + * @return bool + */ + public function IsEnabled() + { + return 0 < $this->Count(); + } + + /** + * @param string $sWord + * + * @return bool + */ + public function AddSecret($sWord) + { + if (\is_string($sWord) && 0 < \strlen(\trim($sWord))) + { + $this->aSecretWords[] = $sWord; + $this->aSecretWords = \array_unique($this->aSecretWords); + } + } + + /** + * @param bool $bShow + * + * @return \MailSo\Log\Logger + */ + public function SetShowSecter($bShow) + { + $this->bShowSecter = !!$bShow; + return $this; + } + + /** + * @param bool $bValue + * + * @return \MailSo\Log\Logger + */ + public function HideErrorNotices($bValue) + { + $this->bHideErrorNotices = !!$bValue; + return $this; + } + + /** + * @return bool + */ + public function IsShowSecter() + { + return $this->bShowSecter; + } + + /** + * @param int $iType + * + * @return \MailSo\Log\Logger + */ + public function AddForbiddenType($iType) + { + $this->aForbiddenTypes[$iType] = true; + + return $this; + } + + /** + * @param int $iType + * + * @return \MailSo\Log\Logger + */ + public function RemoveForbiddenType($iType) + { + $this->aForbiddenTypes[$iType] = false; + return $this; + } + + /** + * @param int $iErrNo + * @param string $sErrStr + * @param string $sErrFile + * @param int $iErrLine + * + * @return bool + */ + public function __phpErrorHandler($iErrNo, $sErrStr, $sErrFile, $iErrLine) + { + $iType = \MailSo\Log\Enumerations\Type::NOTICE_PHP; + switch ($iErrNo) + { + case E_USER_ERROR: + $iType = \MailSo\Log\Enumerations\Type::ERROR_PHP; + break; + case E_USER_WARNING: + $iType = \MailSo\Log\Enumerations\Type::WARNING_PHP; + break; + } + + $this->Write($sErrFile.' [line:'.$iErrLine.', code:'.$iErrNo.']', $iType, 'PHP'); + $this->Write('Error: '.$sErrStr, $iType, 'PHP'); + + return !!(\MailSo\Log\Enumerations\Type::NOTICE === $iType && $this->bHideErrorNotices); + } + + /** + * @return void + */ + public function __loggerShutDown() + { + if ($this->bUsed) + { + $aStatistic = \MailSo\Base\Loader::Statistic(); + if (\is_array($aStatistic)) + { + if (isset($aStatistic['php']['memory_get_peak_usage'])) + { + $this->Write('Memory peak usage: '.$aStatistic['php']['memory_get_peak_usage'], + \MailSo\Log\Enumerations\Type::MEMORY); + } + + if (isset($aStatistic['time'])) + { + $this->Write('Time delta: '.$aStatistic['time'], \MailSo\Log\Enumerations\Type::TIME_DELTA); + } + } + } + } + + /** + * @return bool + */ + public function WriteEmptyLine() + { + $iResult = 1; + + $aLoggers =& $this->GetAsArray(); + foreach ($aLoggers as /* @var $oLogger \MailSo\Log\Driver */ &$oLogger) + { + $iResult &= $oLogger->WriteEmptyLine(); + } + + return (bool) $iResult; + } + + /** + * @param string $sDesc + * @param int $iType = \MailSo\Log\Enumerations\Type::INFO + * @param string $sName = '' + * @param bool $bSearchSecretWords = true + * @param bool $bDiplayCrLf = false + * + * @return bool + */ + public function Write($sDesc, $iType = \MailSo\Log\Enumerations\Type::INFO, + $sName = '', $bSearchSecretWords = true, $bDiplayCrLf = false) + { + if (isset($this->aForbiddenTypes[$iType]) && true === $this->aForbiddenTypes[$iType]) + { + return true; + } + + $this->bUsed = true; + + $oLogger = null; + $aLoggers = array(); + $iResult = 1; + + if ($bSearchSecretWords && !$this->bShowSecter && 0 < \count($this->aSecretWords)) + { + $sDesc = \str_replace($this->aSecretWords, '*******', $sDesc); + } + + $aLoggers =& $this->GetAsArray(); + foreach ($aLoggers as /* @var $oLogger \MailSo\Log\Driver */ $oLogger) + { + $iResult &= $oLogger->Write($sDesc, $iType, $sName, $bDiplayCrLf); + } + + return (bool) $iResult; + } + + /** + * @param mixed $oValue + * @param int $iType = \MailSo\Log\Enumerations\Type::INFO + * @param string $sName = '' + * @param bool $bSearchSecretWords = false + * @param bool $bDiplayCrLf = false + * + * @return bool + */ + public function WriteDump($oValue, $iType = \MailSo\Log\Enumerations\Type::INFO, $sName = '', + $bSearchSecretWords = false, $bDiplayCrLf = false) + { + return $this->Write(\print_r($oValue, true), $iType, $sName, $bSearchSecretWords, $bDiplayCrLf); + } + + /** + * @param \Exception $oException + * @param int $iType = \MailSo\Log\Enumerations\Type::NOTICE + * @param string $sName = '' + * @param bool $bSearchSecretWords = true + * @param bool $bDiplayCrLf = false + * + * @return bool + */ + public function WriteException($oException, $iType = \MailSo\Log\Enumerations\Type::NOTICE, $sName = '', + $bSearchSecretWords = true, $bDiplayCrLf = false) + { + if ($oException instanceof \Exception) + { + if (isset($oException->__LOGINNED__)) + { + return true; + } + + $oException->__LOGINNED__ = true; + + return $this->Write((string) $oException, $iType, $sName, $bSearchSecretWords, $bDiplayCrLf); + } + + return false; + } + + /** + * @param \Exception $oException + * @param int $iType = \MailSo\Log\Enumerations\Type::NOTICE + * @param string $sName = '' + * @param bool $bSearchSecretWords = true + * @param bool $bDiplayCrLf = false + * + * @return bool + */ + public function WriteExceptionShort($oException, $iType = \MailSo\Log\Enumerations\Type::NOTICE, $sName = '', + $bSearchSecretWords = true, $bDiplayCrLf = false) + { + if ($oException instanceof \Exception) + { + if (isset($oException->__LOGINNED__)) + { + return true; + } + + $oException->__LOGINNED__ = true; + + return $this->Write($oException->getMessage(), $iType, $sName, $bSearchSecretWords, $bDiplayCrLf); + } + + return false; + } + + /** + * @param mixed $mData + * @param int $iType = \MailSo\Log\Enumerations\Type::NOTICE + * @param string $sName = '' + * @param bool $bSearchSecretWords = true + * @param bool $bDiplayCrLf = false + * + * @return bool + */ + public function WriteMixed($mData, $iType = null, $sName = '', + $bSearchSecretWords = true, $bDiplayCrLf = false) + { + $iType = null === $iType ? \MailSo\Log\Enumerations\Type::INFO : $iType; + if (\is_array($mData) || \is_object($mData)) + { + if ($mData instanceof \Exception) + { + $iType = null === $iType ? \MailSo\Log\Enumerations\Type::NOTICE : $iType; + return $this->WriteException($mData, $iType, $sName, $bSearchSecretWords, $bDiplayCrLf); + } + else + { + return $this->WriteDump($mData, $iType, $sName, $bSearchSecretWords, $bDiplayCrLf); + } + } + else + { + return $this->Write($mData, $iType, $sName, $bSearchSecretWords, $bDiplayCrLf); + } + + return false; + } +} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mail/Attachment.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mail/Attachment.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mail/Attachment.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mail/Attachment.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mail/AttachmentCollection.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mail/AttachmentCollection.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mail/AttachmentCollection.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mail/AttachmentCollection.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mail/Exceptions/Exception.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mail/Exceptions/Exception.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mail/Exceptions/Exception.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mail/Exceptions/Exception.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mail/Exceptions/NonEmptyFolder.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mail/Exceptions/NonEmptyFolder.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mail/Exceptions/NonEmptyFolder.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mail/Exceptions/NonEmptyFolder.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mail/Exceptions/RuntimeException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mail/Exceptions/RuntimeException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mail/Exceptions/RuntimeException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mail/Exceptions/RuntimeException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mail/Folder.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mail/Folder.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mail/Folder.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mail/Folder.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mail/FolderCollection.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mail/FolderCollection.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mail/FolderCollection.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mail/FolderCollection.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mail/MailClient.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mail/MailClient.php similarity index 96% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mail/MailClient.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mail/MailClient.php index 1e95e251f7a1e14e6fbd23c05ddc0f05ed6f1522..ff0500faf5ad0c911f50f28e8c199177bc9015d3 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mail/MailClient.php +++ b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mail/MailClient.php @@ -1,2677 +1,2677 @@ -oLogger = null; - - $this->oImapClient = \MailSo\Imap\ImapClient::NewInstance(); - $this->oImapClient->SetTimeOuts(10, \MailSo\Config::$ImapTimeout); - } - - /** - * @return \MailSo\Mail\MailClient - */ - public static function NewInstance() - { - return new self(); - } - - /** - * @return \MailSo\Imap\ImapClient - */ - public function ImapClient() - { - return $this->oImapClient; - } - - /** - * @param string $sServerName - * @param int $iPort = 143 - * @param int $iSecurityType = \MailSo\Net\Enumerations\ConnectionSecurityType::AUTO_DETECT - * @param bool $bVerifySsl = false - * - * @return \MailSo\Mail\MailClient - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function Connect($sServerName, $iPort = 143, - $iSecurityType = \MailSo\Net\Enumerations\ConnectionSecurityType::AUTO_DETECT, $bVerifySsl = false) - { - $this->oImapClient->Connect($sServerName, $iPort, $iSecurityType, $bVerifySsl); - return $this; - } - - /** - * @param string $sLogin - * @param string $sPassword - * @param string $sProxyAuthUser = '' - * @param bool $bUseAuthPlainIfSupported = true - * @param bool $bUseAuthCramMd5IfSupported = true - * - * @return \MailSo\Mail\MailClient - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\LoginException - */ - public function Login($sLogin, $sPassword, $sProxyAuthUser = '', - $bUseAuthPlainIfSupported = true, $bUseAuthCramMd5IfSupported = true) - { - $this->oImapClient->Login($sLogin, $sPassword, $sProxyAuthUser, $bUseAuthPlainIfSupported, $bUseAuthCramMd5IfSupported); - return $this; - } - - /** - * @param string $sXOAuth2Token - * - * @return \MailSo\Mail\MailClient - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\LoginException - */ - public function LoginWithXOauth2($sXOAuth2Token) - { - $this->oImapClient->LoginWithXOauth2($sXOAuth2Token); - return $this; - } - - /** - * @return \MailSo\Mail\MailClient - * - * @throws \MailSo\Net\Exceptions\Exception - */ - public function Logout() - { - $this->oImapClient->Logout(); - return $this; - } - - /** - * @return \MailSo\Mail\MailClient - * - * @throws \MailSo\Net\Exceptions\Exception - */ - public function Disconnect() - { - $this->oImapClient->Disconnect(); - return $this; - } - - /** - * @return \MailSo\Mail\MailClient - * - * @throws \MailSo\Net\Exceptions\Exception - */ - public function LogoutAndDisconnect() - { - return $this->Logout()->Disconnect(); - } - - /** - * @return bool - */ - public function IsConnected() - { - return $this->oImapClient->IsConnected(); - } - - /** - * @return bool - */ - public function IsLoggined() - { - return $this->oImapClient->IsLoggined(); - } - - /** - * @return string - */ - private function getEnvelopeOrHeadersRequestStringForSimpleList() - { - return \MailSo\Imap\Enumerations\FetchType::BuildBodyCustomHeaderRequest(array( - \MailSo\Mime\Enumerations\Header::RETURN_PATH, - \MailSo\Mime\Enumerations\Header::RECEIVED, - \MailSo\Mime\Enumerations\Header::MIME_VERSION, - \MailSo\Mime\Enumerations\Header::FROM_, - \MailSo\Mime\Enumerations\Header::TO_, - \MailSo\Mime\Enumerations\Header::CC, - \MailSo\Mime\Enumerations\Header::SENDER, - \MailSo\Mime\Enumerations\Header::REPLY_TO, - \MailSo\Mime\Enumerations\Header::DATE, - \MailSo\Mime\Enumerations\Header::SUBJECT, - \MailSo\Mime\Enumerations\Header::CONTENT_TYPE, - \MailSo\Mime\Enumerations\Header::LIST_UNSUBSCRIBE, - ), true); - } - - /** - * @return string - */ - private function getEnvelopeOrHeadersRequestString() - { - if (\MailSo\Config::$MessageAllHeaders) - { - return \MailSo\Imap\Enumerations\FetchType::BODY_HEADER_PEEK; - } - - return \MailSo\Imap\Enumerations\FetchType::BuildBodyCustomHeaderRequest(array( - \MailSo\Mime\Enumerations\Header::RETURN_PATH, - \MailSo\Mime\Enumerations\Header::RECEIVED, - \MailSo\Mime\Enumerations\Header::MIME_VERSION, - \MailSo\Mime\Enumerations\Header::MESSAGE_ID, - \MailSo\Mime\Enumerations\Header::CONTENT_TYPE, - \MailSo\Mime\Enumerations\Header::FROM_, - \MailSo\Mime\Enumerations\Header::TO_, - \MailSo\Mime\Enumerations\Header::CC, - \MailSo\Mime\Enumerations\Header::BCC, - \MailSo\Mime\Enumerations\Header::SENDER, - \MailSo\Mime\Enumerations\Header::REPLY_TO, - \MailSo\Mime\Enumerations\Header::DELIVERED_TO, - \MailSo\Mime\Enumerations\Header::IN_REPLY_TO, - \MailSo\Mime\Enumerations\Header::REFERENCES, - \MailSo\Mime\Enumerations\Header::DATE, - \MailSo\Mime\Enumerations\Header::SUBJECT, - \MailSo\Mime\Enumerations\Header::SENSITIVITY, - \MailSo\Mime\Enumerations\Header::X_MSMAIL_PRIORITY, - \MailSo\Mime\Enumerations\Header::IMPORTANCE, - \MailSo\Mime\Enumerations\Header::X_PRIORITY, - \MailSo\Mime\Enumerations\Header::X_DRAFT_INFO, - \MailSo\Mime\Enumerations\Header::RETURN_RECEIPT_TO, - \MailSo\Mime\Enumerations\Header::DISPOSITION_NOTIFICATION_TO, - \MailSo\Mime\Enumerations\Header::X_CONFIRM_READING_TO, - \MailSo\Mime\Enumerations\Header::AUTHENTICATION_RESULTS, - \MailSo\Mime\Enumerations\Header::X_DKIM_AUTHENTICATION_RESULTS, - \MailSo\Mime\Enumerations\Header::LIST_UNSUBSCRIBE, - ), true); -// -// return \MailSo\Imap\Enumerations\FetchType::ENVELOPE; - } - - /** - * @param string $sFolderName - * @param string $sMessageFlag - * @param bool $bSetAction = true - * @param bool $sSkipUnsupportedFlag = false - * @param array $aCustomUids = null - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - * @throws \MailSo\Mail\Exceptions\Exception - */ - public function MessageSetFlagToAll($sFolderName, $sMessageFlag, $bSetAction = true, $sSkipUnsupportedFlag = false, $aCustomUids = null) - { - $this->oImapClient->FolderSelect($sFolderName); - - $oFolderInfo = $this->oImapClient->FolderCurrentInformation(); - if (!$oFolderInfo || !$oFolderInfo->IsFlagSupported($sMessageFlag)) - { - if (!$sSkipUnsupportedFlag) - { - throw new \MailSo\Mail\Exceptions\RuntimeException('Message flag "'.$sMessageFlag.'" is not supported.'); - } - } - - if ($oFolderInfo && 0 < $oFolderInfo->Exists) - { - $sStoreAction = $bSetAction - ? \MailSo\Imap\Enumerations\StoreAction::ADD_FLAGS_SILENT - : \MailSo\Imap\Enumerations\StoreAction::REMOVE_FLAGS_SILENT - ; - - if (is_array($aCustomUids)) - { - if (0 < count($aCustomUids)) - { - $this->oImapClient->MessageStoreFlag(implode(',', $aCustomUids), true, array($sMessageFlag), $sStoreAction); - } - } - else - { - $this->oImapClient->MessageStoreFlag('1:*', false, array($sMessageFlag), $sStoreAction); - } - } - } - - /** - * @param string $sFolderName - * @param array $aIndexRange - * @param bool $bIndexIsUid - * @param string $sMessageFlag - * @param bool $bSetAction = true - * @param bool $sSkipUnsupportedFlag = false - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - * @throws \MailSo\Mail\Exceptions\Exception - */ - public function MessageSetFlag($sFolderName, $aIndexRange, $bIndexIsUid, $sMessageFlag, $bSetAction = true, $sSkipUnsupportedFlag = false) - { - $this->oImapClient->FolderSelect($sFolderName); - - $oFolderInfo = $this->oImapClient->FolderCurrentInformation(); - if (!$oFolderInfo || !$oFolderInfo->IsFlagSupported($sMessageFlag)) - { - if (!$sSkipUnsupportedFlag) - { - throw new \MailSo\Mail\Exceptions\RuntimeException('Message flag "'.$sMessageFlag.'" is not supported.'); - } - } - else - { - $sStoreAction = $bSetAction - ? \MailSo\Imap\Enumerations\StoreAction::ADD_FLAGS_SILENT - : \MailSo\Imap\Enumerations\StoreAction::REMOVE_FLAGS_SILENT - ; - - $this->oImapClient->MessageStoreFlag(\MailSo\Base\Utils::PrepearFetchSequence($aIndexRange), - $bIndexIsUid, array($sMessageFlag), $sStoreAction); - } - } - - /** - * @param string $sFolderName - * @param array $aIndexRange - * @param bool $bIndexIsUid - * @param bool $bSetAction = true - * @param bool $sSkipUnsupportedFlag = false - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function MessageSetFlagged($sFolderName, $aIndexRange, $bIndexIsUid, $bSetAction = true, $sSkipUnsupportedFlag = false) - { - $this->MessageSetFlag($sFolderName, $aIndexRange, $bIndexIsUid, - \MailSo\Imap\Enumerations\MessageFlag::FLAGGED, $bSetAction, $sSkipUnsupportedFlag); - } - - /** - * @param string $sFolderName - * @param bool $bSetAction = true - * @param array $aCustomUids = null - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function MessageSetSeenToAll($sFolderName, $bSetAction = true, $aCustomUids = null) - { - $this->MessageSetFlagToAll($sFolderName, \MailSo\Imap\Enumerations\MessageFlag::SEEN, $bSetAction, true, $aCustomUids); - } - - /** - * @param string $sFolderName - * @param array $aIndexRange - * @param bool $bIndexIsUid - * @param bool $bSetAction = true - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function MessageSetSeen($sFolderName, $aIndexRange, $bIndexIsUid, $bSetAction = true) - { - $this->MessageSetFlag($sFolderName, $aIndexRange, $bIndexIsUid, - \MailSo\Imap\Enumerations\MessageFlag::SEEN, $bSetAction, true); - } - - /** - * @param string $sFolderName - * @param int $iIndex - * @param bool $bIndexIsUid = true - * @param \MailSo\Cache\CacheClient $oCacher = null - * @param int $iBodyTextLimit = null - * - * @return \MailSo\Mail\Message|false - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function Message($sFolderName, $iIndex, $bIndexIsUid = true, $oCacher = null, $iBodyTextLimit = null) - { - if (!\MailSo\Base\Validator::RangeInt($iIndex, 1)) - { - throw new \MailSo\Base\Exceptions\InvalidArgumentException(); - } - - $this->oImapClient->FolderSelect($sFolderName); - - $oBodyStructure = null; - $oMessage = false; - - $aBodyPeekMimeIndexes = array(); - $aSignatureMimeIndexes = array(); - - $aFetchResponse = $this->oImapClient->Fetch(array(\MailSo\Imap\Enumerations\FetchType::BODYSTRUCTURE), $iIndex, $bIndexIsUid); - if (0 < \count($aFetchResponse) && isset($aFetchResponse[0])) - { - $oBodyStructure = $aFetchResponse[0]->GetFetchBodyStructure(); - if ($oBodyStructure) - { - $aTextParts = $oBodyStructure->SearchHtmlOrPlainParts(); - if (is_array($aTextParts) && 0 < \count($aTextParts)) - { - foreach ($aTextParts as $oPart) - { - $aBodyPeekMimeIndexes[] = array($oPart->PartID(), $oPart->Size()); - } - } - - $aSignatureParts = $oBodyStructure->SearchByContentType('application/pgp-signature'); - if (is_array($aSignatureParts) && 0 < \count($aSignatureParts)) - { - foreach ($aSignatureParts as $oPart) - { - $aSignatureMimeIndexes[] = $oPart->PartID(); - } - } - } - } - - $aFetchItems = array( - \MailSo\Imap\Enumerations\FetchType::INDEX, - \MailSo\Imap\Enumerations\FetchType::UID, - \MailSo\Imap\Enumerations\FetchType::RFC822_SIZE, - \MailSo\Imap\Enumerations\FetchType::INTERNALDATE, - \MailSo\Imap\Enumerations\FetchType::FLAGS, - $this->getEnvelopeOrHeadersRequestString() - ); - - if (0 < \count($aBodyPeekMimeIndexes)) - { - foreach ($aBodyPeekMimeIndexes as $aTextMimeData) - { - $sLine = \MailSo\Imap\Enumerations\FetchType::BODY_PEEK.'['.$aTextMimeData[0].']'; - if (\is_numeric($iBodyTextLimit) && 0 < $iBodyTextLimit && $iBodyTextLimit < $aTextMimeData[1]) - { - $sLine .= '<0.'.((int) $iBodyTextLimit).'>'; - } - - $aFetchItems[] = $sLine; - } - } - - if (0 < \count($aSignatureMimeIndexes)) - { - foreach ($aSignatureMimeIndexes as $sTextMimeIndex) - { - $aFetchItems[] = \MailSo\Imap\Enumerations\FetchType::BODY_PEEK.'['.$sTextMimeIndex.']'; - } - } - - if (!$oBodyStructure) - { - $aFetchItems[] = \MailSo\Imap\Enumerations\FetchType::BODYSTRUCTURE; - } - - $aFetchResponse = $this->oImapClient->Fetch($aFetchItems, $iIndex, $bIndexIsUid); - if (0 < \count($aFetchResponse)) - { - $oMessage = \MailSo\Mail\Message::NewFetchResponseInstance( - $sFolderName, $aFetchResponse[0], $oBodyStructure); - } - - return $oMessage; - } - - /** - * @param mixed $mCallback - * @param string $sFolderName - * @param int $iIndex - * @param bool $bIndexIsUid = true, - * @param string $sMimeIndex = '' - * - * @return bool - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function MessageMimeStream($mCallback, $sFolderName, $iIndex, $bIndexIsUid = true, $sMimeIndex = '') - { - if (!is_callable($mCallback)) - { - throw new \MailSo\Base\Exceptions\InvalidArgumentException(); - } - - $this->oImapClient->FolderSelect($sFolderName); - - $sFileName = ''; - $sContentType = ''; - $sMailEncodingName = ''; - - $sMimeIndex = trim($sMimeIndex); - $aFetchResponse = $this->oImapClient->Fetch(array( - 0 === \strlen($sMimeIndex) - ? \MailSo\Imap\Enumerations\FetchType::BODY_HEADER_PEEK - : \MailSo\Imap\Enumerations\FetchType::BODY_PEEK.'['.$sMimeIndex.'.MIME]' - ), $iIndex, $bIndexIsUid); - - if (0 < \count($aFetchResponse)) - { - $sMime = $aFetchResponse[0]->GetFetchValue( - 0 === \strlen($sMimeIndex) - ? \MailSo\Imap\Enumerations\FetchType::BODY_HEADER - : \MailSo\Imap\Enumerations\FetchType::BODY.'['.$sMimeIndex.'.MIME]' - ); - - if (0 < \strlen($sMime)) - { - $oHeaders = \MailSo\Mime\HeaderCollection::NewInstance()->Parse($sMime); - - if (0 < \strlen($sMimeIndex)) - { - $sFileName = $oHeaders->ParameterValue( - \MailSo\Mime\Enumerations\Header::CONTENT_DISPOSITION, - \MailSo\Mime\Enumerations\Parameter::FILENAME); - - if (0 === \strlen($sFileName)) - { - $sFileName = $oHeaders->ParameterValue( - \MailSo\Mime\Enumerations\Header::CONTENT_TYPE, - \MailSo\Mime\Enumerations\Parameter::NAME); - } - - $sMailEncodingName = $oHeaders->ValueByName( - \MailSo\Mime\Enumerations\Header::CONTENT_TRANSFER_ENCODING); - - $sContentType = $oHeaders->ValueByName( - \MailSo\Mime\Enumerations\Header::CONTENT_TYPE); - } - else - { - $sSubject = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::SUBJECT); - - $sFileName = 0 === \strlen($sSubject) ? (string) $iIndex : $sSubject; - $sFileName .= '.eml'; - - $sContentType = 'message/rfc822'; - } - } - } - - $aFetchResponse = $this->oImapClient->Fetch(array( - array(\MailSo\Imap\Enumerations\FetchType::BODY_PEEK.'['.$sMimeIndex.']', - function ($sParent, $sLiteralAtomUpperCase, $rImapLiteralStream) use ($mCallback, $sMimeIndex, $sMailEncodingName, $sContentType, $sFileName) - { - if (0 < \strlen($sLiteralAtomUpperCase)) - { - if (is_resource($rImapLiteralStream) && 'FETCH' === $sParent) - { - $rMessageMimeIndexStream = (0 === \strlen($sMailEncodingName)) - ? $rImapLiteralStream - : \MailSo\Base\StreamWrappers\Binary::CreateStream($rImapLiteralStream, - \MailSo\Base\StreamWrappers\Binary::GetInlineDecodeOrEncodeFunctionName( - $sMailEncodingName, true)); - - \call_user_func($mCallback, $rMessageMimeIndexStream, $sContentType, $sFileName, $sMimeIndex); - } - } - } - )), $iIndex, $bIndexIsUid); - - return ($aFetchResponse && 1 === \count($aFetchResponse)); - } - - /** - * @param string $sFolder - * @param array $aIndexRange - * @param bool $bIndexIsUid - * @param bool $bUseExpunge = true - * @param bool $bExpungeAll = false - * - * @return \MailSo\Mail\MailClient - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function MessageDelete($sFolder, $aIndexRange, $bIndexIsUid, $bUseExpunge = true, $bExpungeAll = false) - { - if (0 === \strlen($sFolder) || !\is_array($aIndexRange) || 0 === \count($aIndexRange)) - { - throw new \MailSo\Base\Exceptions\InvalidArgumentException(); - } - - $this->oImapClient->FolderSelect($sFolder); - - $sIndexRange = \MailSo\Base\Utils::PrepearFetchSequence($aIndexRange); - - $this->oImapClient->MessageStoreFlag($sIndexRange, $bIndexIsUid, - array(\MailSo\Imap\Enumerations\MessageFlag::DELETED), - \MailSo\Imap\Enumerations\StoreAction::ADD_FLAGS_SILENT - ); - - if ($bUseExpunge) - { - $this->oImapClient->MessageExpunge($bIndexIsUid ? $sIndexRange : '', $bIndexIsUid, $bExpungeAll); - } - - return $this; - } - - /** - * @param string $sFromFolder - * @param string $sToFolder - * @param array $aIndexRange - * @param bool $bIndexIsUid - * @param bool $bUseMoveSupported = false - * @param bool $bExpungeAll = false - * - * @return \MailSo\Mail\MailClient - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function MessageMove($sFromFolder, $sToFolder, $aIndexRange, $bIndexIsUid, $bUseMoveSupported = false, $bExpungeAll = false) - { - if (0 === \strlen($sFromFolder) || 0 === \strlen($sToFolder) || - !\is_array($aIndexRange) || 0 === \count($aIndexRange)) - { - throw new \MailSo\Base\Exceptions\InvalidArgumentException(); - } - - $this->oImapClient->FolderSelect($sFromFolder); - - if ($bUseMoveSupported && $this->oImapClient->IsSupported('MOVE')) - { - $this->oImapClient->MessageMove($sToFolder, - \MailSo\Base\Utils::PrepearFetchSequence($aIndexRange), $bIndexIsUid); - } - else - { - $this->oImapClient->MessageCopy($sToFolder, - \MailSo\Base\Utils::PrepearFetchSequence($aIndexRange), $bIndexIsUid); - - $this->MessageDelete($sFromFolder, $aIndexRange, $bIndexIsUid, true, $bExpungeAll); - } - - return $this; - } - - /** - * @param string $sFromFolder - * @param string $sToFolder - * @param array $aIndexRange - * @param bool $bIndexIsUid - * - * @return \MailSo\Mail\MailClient - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function MessageCopy($sFromFolder, $sToFolder, $aIndexRange, $bIndexIsUid) - { - if (0 === \strlen($sFromFolder) || 0 === \strlen($sToFolder) || - !\is_array($aIndexRange) || 0 === \count($aIndexRange)) - { - throw new \MailSo\Base\Exceptions\InvalidArgumentException(); - } - - $this->oImapClient->FolderSelect($sFromFolder); - $this->oImapClient->MessageCopy($sToFolder, - \MailSo\Base\Utils::PrepearFetchSequence($aIndexRange), $bIndexIsUid); - - return $this; - } - - /** - * @return \MailSo\Mail\MailClient - * - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function FolderUnSelect() - { - if ($this->oImapClient->IsSelected()) - { - $this->oImapClient->FolderUnSelect(); - } - - return $this; - } - - /** - * @param resource $rMessageStream - * @param int $iMessageStreamSize - * @param string $sFolderToSave - * @param array $aAppendFlags = null - * @param int $iUid = null - * - * @return \MailSo\Mail\MailClient - */ - public function MessageAppendStream($rMessageStream, $iMessageStreamSize, $sFolderToSave, $aAppendFlags = null, &$iUid = null) - { - if (!\is_resource($rMessageStream) || 0 === \strlen($sFolderToSave)) - { - throw new \MailSo\Base\Exceptions\InvalidArgumentException(); - } - - $this->oImapClient->MessageAppendStream( - $sFolderToSave, $rMessageStream, $iMessageStreamSize, $aAppendFlags, $iUid); - - return $this; - } - - /** - * @param string $sMessageFileName - * @param string $sFolderToSave - * @param array $aAppendFlags = null - * @param int &$iUid = null - * - * @return \MailSo\Mail\MailClient - */ - public function MessageAppendFile($sMessageFileName, $sFolderToSave, $aAppendFlags = null, &$iUid = null) - { - if (!@\is_file($sMessageFileName) || !@\is_readable($sMessageFileName)) - { - throw new \MailSo\Base\Exceptions\InvalidArgumentException(); - } - - $iMessageStreamSize = \filesize($sMessageFileName); - $rMessageStream = \fopen($sMessageFileName, 'rb'); - - $this->MessageAppendStream($rMessageStream, $iMessageStreamSize, $sFolderToSave, $aAppendFlags, $iUid); - - if (\is_resource($rMessageStream)) - { - @fclose($rMessageStream); - } - - return $this; - } - - /** - * @param string $sFolderName - * @param int $iCount - * @param int $iUnseenCount - * @param string $sUidNext - * @param string $sHighestModSeq - * - * @return void - */ - protected function initFolderValues($sFolderName, &$iCount, &$iUnseenCount, - &$sUidNext, &$sHighestModSeq = '') - { - $aTypes = array( - \MailSo\Imap\Enumerations\FolderResponseStatus::MESSAGES, - \MailSo\Imap\Enumerations\FolderResponseStatus::UNSEEN, - \MailSo\Imap\Enumerations\FolderResponseStatus::UIDNEXT - ); - - if ($this->oImapClient->IsSupported('CONDSTORE')) - { - $aTypes[] = \MailSo\Imap\Enumerations\FolderResponseStatus::HIGHESTMODSEQ; - } - - $aFolderStatus = $this->oImapClient->FolderStatus($sFolderName, $aTypes); - - $iCount = isset($aFolderStatus[\MailSo\Imap\Enumerations\FolderResponseStatus::MESSAGES]) - ? (int) $aFolderStatus[\MailSo\Imap\Enumerations\FolderResponseStatus::MESSAGES] : 0; - - $iUnseenCount = isset($aFolderStatus[\MailSo\Imap\Enumerations\FolderResponseStatus::UNSEEN]) - ? (int) $aFolderStatus[\MailSo\Imap\Enumerations\FolderResponseStatus::UNSEEN] : 0; - - $sUidNext = isset($aFolderStatus[\MailSo\Imap\Enumerations\FolderResponseStatus::UIDNEXT]) - ? (string) $aFolderStatus[\MailSo\Imap\Enumerations\FolderResponseStatus::UIDNEXT] : '0'; - - $sHighestModSeq = isset($aFolderStatus[\MailSo\Imap\Enumerations\FolderResponseStatus::HIGHESTMODSEQ]) - ? (string) $aFolderStatus[\MailSo\Imap\Enumerations\FolderResponseStatus::HIGHESTMODSEQ] : ''; - - if ($this->IsGmail() && - ('INBOX' === $sFolderName || '[gmail]' === \strtolower(\substr($sFolderName, 0, 7)))) - { - $oFolder = $this->oImapClient->FolderCurrentInformation(); - if ($oFolder && null !== $oFolder->Exists && $oFolder->FolderName === $sFolderName) - { - $iSubCount = (int) $oFolder->Exists; - if (0 < $iSubCount && $iSubCount < $iCount) - { - $iCount = $iSubCount; - } - } - } - } - - /** - * @return string - */ - public function GenerateImapClientHash() - { - return \md5('ImapClientHash/'. - $this->oImapClient->GetLogginedUser().'@'. - $this->oImapClient->GetConnectedHost().':'. - $this->oImapClient->GetConnectedPort() - ); - } - - /** - * @param string $sFolder - * @param int $iCount - * @param int $iUnseenCount - * @param string $sUidNext - * @param string $sHighestModSeq = '' - * - * @return string - */ - public function GenerateFolderHash($sFolder, $iCount, $iUnseenCount, $sUidNext, $sHighestModSeq = '') - { - $iUnseenCount = 0; // unneccessery - return \md5('FolderHash/'.$sFolder.'-'.$iCount.'-'.$iUnseenCount.'-'.$sUidNext.'-'. - $sHighestModSeq.'-'.$this->GenerateImapClientHash().'-'. - \MailSo\Config::$MessageListPermanentFilter - ); - } - - /** - * @param string $sFolderName - * @param string $sPrevUidNext - * @param string $sCurrentUidNext - * - * @return array - */ - private function getFolderNextMessageInformation($sFolderName, $sPrevUidNext, $sCurrentUidNext) - { - $aNewMessages = array(); - - if (0 < \strlen($sPrevUidNext) && (string) $sPrevUidNext !== (string) $sCurrentUidNext) - { - $this->oImapClient->FolderSelect($sFolderName); - - $aFetchResponse = $this->oImapClient->Fetch(array( - \MailSo\Imap\Enumerations\FetchType::INDEX, - \MailSo\Imap\Enumerations\FetchType::UID, - \MailSo\Imap\Enumerations\FetchType::FLAGS, - \MailSo\Imap\Enumerations\FetchType::BuildBodyCustomHeaderRequest(array( - \MailSo\Mime\Enumerations\Header::FROM_, - \MailSo\Mime\Enumerations\Header::SUBJECT, - \MailSo\Mime\Enumerations\Header::CONTENT_TYPE - )) - ), $sPrevUidNext.':*', true); - - if (\is_array($aFetchResponse) && 0 < \count($aFetchResponse)) - { - foreach ($aFetchResponse as /* @var $oFetchResponse \MailSo\Imap\FetchResponse */ $oFetchResponse) - { - $aFlags = \array_map('strtolower', $oFetchResponse->GetFetchValue( - \MailSo\Imap\Enumerations\FetchType::FLAGS)); - - if (!\in_array(\strtolower(\MailSo\Imap\Enumerations\MessageFlag::SEEN), $aFlags)) - { - $sUid = $oFetchResponse->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::UID); - $sHeaders = $oFetchResponse->GetHeaderFieldsValue(); - - $oHeaders = \MailSo\Mime\HeaderCollection::NewInstance()->Parse($sHeaders); - - $sContentTypeCharset = $oHeaders->ParameterValue( - \MailSo\Mime\Enumerations\Header::CONTENT_TYPE, - \MailSo\Mime\Enumerations\Parameter::CHARSET - ); - - $sCharset = ''; - if (0 < \strlen($sContentTypeCharset)) - { - $sCharset = $sContentTypeCharset; - } - - if (0 < \strlen($sCharset)) - { - $oHeaders->SetParentCharset($sCharset); - } - - $aNewMessages[] = array( - 'Folder' => $sFolderName, - 'Uid' => $sUid, - 'Subject' => $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::SUBJECT, 0 === \strlen($sCharset)), - 'From' => $oHeaders->GetAsEmailCollection(\MailSo\Mime\Enumerations\Header::FROM_, 0 === \strlen($sCharset)) - ); - } - } - } - } - - return $aNewMessages; - } - - /** - * @param string $sFolderName - * @param string $sPrevUidNext = '' - * @param array $aUids = '' - * - * @return string - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function FolderInformation($sFolderName, $sPrevUidNext = '', $aUids = array()) - { - $aFlags = array(); - - $bSelect = false; - if ($this->IsGmail() && - ('INBOX' === $sFolderName || '[gmail]' === \strtolower(\substr($sFolderName, 0, 7)))) - { - $this->oImapClient->FolderSelect($sFolderName); - $bSelect = true; - } - - if (\is_array($aUids) && 0 < \count($aUids)) - { - if (!$bSelect) - { - $this->oImapClient->FolderSelect($sFolderName); - } - - $aFetchResponse = $this->oImapClient->Fetch(array( - \MailSo\Imap\Enumerations\FetchType::INDEX, - \MailSo\Imap\Enumerations\FetchType::UID, - \MailSo\Imap\Enumerations\FetchType::FLAGS - ), \MailSo\Base\Utils::PrepearFetchSequence($aUids), true); - - if (\is_array($aFetchResponse) && 0 < \count($aFetchResponse)) - { - foreach ($aFetchResponse as $oFetchResponse) - { - $sUid = $oFetchResponse->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::UID); - $aFlags[(\is_numeric($sUid) ? (int) $sUid : 0)] = - $oFetchResponse->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::FLAGS); - } - } - } - - $iCount = 0; - $iUnseenCount = 0; - $sUidNext = '0'; - $sHighestModSeq = ''; - - $this->initFolderValues($sFolderName, $iCount, $iUnseenCount, $sUidNext, $sHighestModSeq); - - $aResult = array( - 'Folder' => $sFolderName, - 'Hash' => $this->GenerateFolderHash($sFolderName, $iCount, $iUnseenCount, $sUidNext, $sHighestModSeq), - 'MessageCount' => $iCount, - 'MessageUnseenCount' => $iUnseenCount, - 'UidNext' => $sUidNext, - 'Flags' => $aFlags, - 'HighestModSeq' => $sHighestModSeq, - 'NewMessages' => 'INBOX' === $sFolderName && \MailSo\Config::$CheckNewMessages ? - $this->getFolderNextMessageInformation($sFolderName, $sPrevUidNext, $sUidNext) : array() - ); - - return $aResult; - } - - /** - * @param string $sFolderName - * - * @return string - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function FolderHash($sFolderName) - { - $iCount = 0; - $iUnseenCount = 0; - $sUidNext = '0'; - $sHighestModSeq = ''; - - $this->initFolderValues($sFolderName, $iCount, $iUnseenCount, $sUidNext, $sHighestModSeq); - - return $this->GenerateFolderHash($sFolderName, $iCount, $iUnseenCount, $sUidNext, $sHighestModSeq); - } - - /** - * @return int - * - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function InboxUnreadCount() - { - $aFolderStatus = $this->oImapClient->FolderStatus('INBOX', array( - \MailSo\Imap\Enumerations\FolderResponseStatus::UNSEEN - )); - - $iResult = isset($aFolderStatus[\MailSo\Imap\Enumerations\FolderResponseStatus::UNSEEN]) ? - (int) $aFolderStatus[\MailSo\Imap\Enumerations\FolderResponseStatus::UNSEEN] : 0; - - return 0 < $iResult ? $iResult : 0; - } - - /** - * @return bool - */ - public function IsGmail() - { - return 'ssl://imap.gmail.com' === \strtolower($this->oImapClient->GetConnectedHost()); - } - - /** - * @param string $sSearch - * @param bool $bDetectGmail = true - * - * @return string - */ - private function escapeSearchString($sSearch, $bDetectGmail = true) - { - return !\MailSo\Base\Utils::IsAscii($sSearch) - ? '{'.\strlen($sSearch).'}'."\r\n".$sSearch : $this->oImapClient->EscapeString($sSearch); -// return ($bDetectGmail && !\MailSo\Base\Utils::IsAscii($sSearch) && $this->IsGmail()) -// ? '{'.\strlen($sSearch).'+}'."\r\n".$sSearch : $this->oImapClient->EscapeString($sSearch); - } - - /** - * @param string $sDate - * @param int $iTimeZoneOffset - * - * @return int - */ - private function parseSearchDate($sDate, $iTimeZoneOffset) - { - $iResult = 0; - if (0 < \strlen($sDate)) - { - $oDateTime = \DateTime::createFromFormat('Y.m.d', $sDate, \MailSo\Base\DateTimeHelper::GetUtcTimeZoneObject()); - return $oDateTime ? $oDateTime->getTimestamp() - $iTimeZoneOffset : 0; - } - - return $iResult; - } - - /** - * @param string $sSize - * - * @return int - */ - private function parseFriendlySize($sSize) - { - $sSize = preg_replace('/[^0-9bBkKmM]/', '', $sSize); - - $iResult = 0; - $aMatch = array(); - - if (\preg_match('/([\d]+)(B|KB|M|MB|G|GB)$/i', $sSize, $aMatch) && isset($aMatch[1], $aMatch[2])) - { - $iResult = (int) $aMatch[1]; - switch (\strtoupper($aMatch[2])) - { - case 'K': - case 'KB': - $iResult *= 1024; - case 'M': - case 'MB': - $iResult *= 1024; - case 'G': - case 'GB': - $iResult *= 1024; - } - } - else - { - $iResult = (int) $sSize; - } - - return $iResult; - } - - /** - * @param string $sSearch - * - * @return array - */ - private function parseSearchString($sSearch) - { - $aResult = array( - 'OTHER' => '' - ); - - $aCache = array(); - - $sReg = 'e?mail|from|to|subject|has|is|date|text|body|size|larger|bigger|smaller|maxsize|minsize'; - - $sSearch = \MailSo\Base\Utils::StripSpaces($sSearch); - $sSearch = \trim(\preg_replace('/('.$sReg.'): /i', '\\1:', $sSearch)); - - $mMatch = array(); - \preg_match_all('/".*?(? $sName) - { - if (isset($mMatch[2][$iIndex]) && 0 < \strlen($mMatch[2][$iIndex])) - { - $sName = \strtoupper($sName); - $sValue = $mMatch[2][$iIndex]; - switch ($sName) - { - case 'TEXT': - case 'BODY': - case 'EMAIL': - case 'MAIL': - case 'FROM': - case 'TO': - case 'SUBJECT': - case 'IS': - case 'HAS': - case 'SIZE': - case 'SMALLER': - case 'LARGER': - case 'BIGGER': - case 'MAXSIZE': - case 'MINSIZE': - case 'DATE': - if ('MAIL' === $sName) - { - $sName = 'EMAIL'; - } - if ('BODY' === $sName) - { - $sName = 'TEXT'; - } - if ('SIZE' === $sName || 'BIGGER' === $sName || 'MINSIZE' === $sName) - { - $sName = 'LARGER'; - } - if ('MAXSIZE' === $sName) - { - $sName = 'SMALLER'; - } - $aResult[$sName] = $sValue; - break; - } - } - } - } - - $aResult['OTHER'] = $sSearch; - foreach ($aResult as $sName => $sValue) - { - if (isset($aCache[$sValue])) - { - $aResult[$sName] = \trim($aCache[$sValue], '"\' '); - } - } - - return $aResult; - } - - /** - * @param string $sSearch - * @param string $sFilter - * @param int $iTimeZoneOffset = 0 - * @param bool $bUseCache = true - * - * @return string - */ - private function getImapSearchCriterias($sSearch, $sFilter, $iTimeZoneOffset = 0, &$bUseCache = true) - { - $bUseCache = true; - $iTimeFilter = 0; - $aCriteriasResult = array(); - - if (0 < \MailSo\Config::$MessageListDateFilter) - { - $iD = \time() - 3600 * 24 * 30 * \MailSo\Config::$MessageListDateFilter; - $iTimeFilter = \gmmktime(1, 1, 1, \gmdate('n', $iD), 1, \gmdate('Y', $iD)); - } - - if (0 < \strlen(\trim($sSearch))) - { - $sGmailRawSearch = ''; - $sResultBodyTextSearch = ''; - - $aLines = $this->parseSearchString($sSearch); - $bIsGmail = $this->oImapClient->IsSupported('X-GM-EXT-1'); - - if (1 === \count($aLines) && isset($aLines['OTHER'])) - { - $sValue = $this->escapeSearchString($aLines['OTHER']); - - if (\MailSo\Config::$MessageListFastSimpleSearch) - { - $aCriteriasResult[] = 'OR OR OR'; - $aCriteriasResult[] = 'FROM'; - $aCriteriasResult[] = $sValue; - $aCriteriasResult[] = 'TO'; - $aCriteriasResult[] = $sValue; - $aCriteriasResult[] = 'CC'; - $aCriteriasResult[] = $sValue; - $aCriteriasResult[] = 'SUBJECT'; - $aCriteriasResult[] = $sValue; - } - else - { - $aCriteriasResult[] = 'TEXT'; - $aCriteriasResult[] = $sValue; - } - } - else - { - if (isset($aLines['EMAIL'])) - { - $sValue = $this->escapeSearchString($aLines['EMAIL']); - - $aCriteriasResult[] = 'OR OR'; - $aCriteriasResult[] = 'FROM'; - $aCriteriasResult[] = $sValue; - $aCriteriasResult[] = 'TO'; - $aCriteriasResult[] = $sValue; - $aCriteriasResult[] = 'CC'; - $aCriteriasResult[] = $sValue; - - unset($aLines['EMAIL']); - } - - if (isset($aLines['TO'])) - { - $sValue = $this->escapeSearchString($aLines['TO']); - - $aCriteriasResult[] = 'OR'; - $aCriteriasResult[] = 'TO'; - $aCriteriasResult[] = $sValue; - $aCriteriasResult[] = 'CC'; - $aCriteriasResult[] = $sValue; - - unset($aLines['TO']); - } - - $sMainText = ''; - foreach ($aLines as $sName => $sRawValue) - { - if ('' === \trim($sRawValue)) - { - continue; - } - - $sValue = $this->escapeSearchString($sRawValue); - switch ($sName) - { - case 'FROM': - $aCriteriasResult[] = 'FROM'; - $aCriteriasResult[] = $sValue; - break; - case 'SUBJECT': - $aCriteriasResult[] = 'SUBJECT'; - $aCriteriasResult[] = $sValue; - break; - case 'OTHER': - case 'TEXT': - $sMainText .= ' '.$sRawValue; - break; - case 'HAS': - $aValue = \explode(',', \strtolower($sRawValue)); - $aValue = \array_map('trim', $aValue); - - $aCompareArray = array('file', 'files', 'attach', 'attachs', 'attachment', 'attachments'); - if (\count($aCompareArray) > \count(\array_diff($aCompareArray, $aValue))) - { - if ($bIsGmail) - { - $sGmailRawSearch .= ' has:attachment'; - } - else - { - // Simple, is not detailed search (Sometimes doesn't work) - $aCriteriasResult[] = 'OR OR OR'; - $aCriteriasResult[] = 'HEADER Content-Type application/'; - $aCriteriasResult[] = 'HEADER Content-Type multipart/m'; - $aCriteriasResult[] = 'HEADER Content-Type multipart/signed'; - $aCriteriasResult[] = 'HEADER Content-Type multipart/report'; - } - } - - case 'IS': - $aValue = \explode(',', \strtolower($sRawValue)); - $aValue = \array_map('trim', $aValue); - - $aCompareArray = array('flag', 'flagged', 'star', 'starred', 'pinned'); - $aCompareArray2 = array('unflag', 'unflagged', 'unstar', 'unstarred', 'unpinned'); - if (\count($aCompareArray) > \count(\array_diff($aCompareArray, $aValue))) - { - $aCriteriasResult[] = 'FLAGGED'; - $bUseCache = false; - } - else if (\count($aCompareArray2) > \count(\array_diff($aCompareArray2, $aValue))) - { - $aCriteriasResult[] = 'UNFLAGGED'; - $bUseCache = false; - } - - $aCompareArray = array('unread', 'unseen'); - $aCompareArray2 = array('read', 'seen'); - if (\count($aCompareArray) > \count(\array_diff($aCompareArray, $aValue))) - { - $aCriteriasResult[] = 'UNSEEN'; - $bUseCache = false; - } - else if (\count($aCompareArray2) > \count(\array_diff($aCompareArray2, $aValue))) - { - $aCriteriasResult[] = 'SEEN'; - $bUseCache = false; - } - break; - - case 'LARGER': - $aCriteriasResult[] = 'LARGER'; - $aCriteriasResult[] = $this->parseFriendlySize($sRawValue); - break; - case 'SMALLER': - $aCriteriasResult[] = 'SMALLER'; - $aCriteriasResult[] = $this->parseFriendlySize($sRawValue); - break; - case 'DATE': - $iDateStampFrom = $iDateStampTo = 0; - - $sDate = $sRawValue; - $aDate = \explode('/', $sDate); - - if (\is_array($aDate) && 2 === \count($aDate)) - { - if (0 < \strlen($aDate[0])) - { - $iDateStampFrom = $this->parseSearchDate($aDate[0], $iTimeZoneOffset); - } - - if (0 < \strlen($aDate[1])) - { - $iDateStampTo = $this->parseSearchDate($aDate[1], $iTimeZoneOffset); - $iDateStampTo += 60 * 60 * 24; - } - } - else - { - if (0 < \strlen($sDate)) - { - $iDateStampFrom = $this->parseSearchDate($sDate, $iTimeZoneOffset); - $iDateStampTo = $iDateStampFrom + 60 * 60 * 24; - } - } - - if (0 < $iDateStampFrom) - { - $aCriteriasResult[] = 'SINCE'; - $aCriteriasResult[] = \gmdate('j-M-Y', $iTimeFilter > $iDateStampFrom ? - $iTimeFilter : $iDateStampFrom); - - $iTimeFilter = 0; - } - - if (0 < $iDateStampTo) - { - $aCriteriasResult[] = 'BEFORE'; - $aCriteriasResult[] = \gmdate('j-M-Y', $iDateStampTo); - } - break; - } - } - - if ('' !== \trim($sMainText)) - { - $sMainText = \trim(\MailSo\Base\Utils::StripSpaces($sMainText), '"'); - if ($bIsGmail) - { - $sGmailRawSearch .= ' '.$sMainText; - } - else - { - $sResultBodyTextSearch .= ' '.$sMainText; - } - } - } - - $sGmailRawSearch = \trim($sGmailRawSearch); - if ($bIsGmail && 0 < \strlen($sGmailRawSearch)) - { - $aCriteriasResult[] = 'X-GM-RAW'; - $aCriteriasResult[] = $this->escapeSearchString($sGmailRawSearch, false); - } - - $sResultBodyTextSearch = \trim($sResultBodyTextSearch); - if (0 < \strlen($sResultBodyTextSearch)) - { - $aCriteriasResult[] = 'BODY'; - $aCriteriasResult[] = $this->escapeSearchString($sResultBodyTextSearch); - } - } - - $sCriteriasResult = \trim(\implode(' ', $aCriteriasResult)); - - if (0 < $iTimeFilter) - { - $sCriteriasResult .= ' SINCE '.\gmdate('j-M-Y', $iTimeFilter); - } - - $sCriteriasResult = \trim($sCriteriasResult); - if (\MailSo\Config::$MessageListUndeletedOnly) - { - $sCriteriasResult = \trim($sCriteriasResult.' UNDELETED'); - } - - $sFilter = \trim($sFilter); - if ('' !== $sFilter) - { - $sCriteriasResult .= ' '.$sFilter; - } - - $sCriteriasResult = \trim($sCriteriasResult); - if ('' !== \MailSo\Config::$MessageListPermanentFilter) - { - $sCriteriasResult = \trim($sCriteriasResult.' '.\MailSo\Config::$MessageListPermanentFilter); - } - - $sCriteriasResult = \trim($sCriteriasResult); - if ('' === $sCriteriasResult) - { - $sCriteriasResult = 'ALL'; - } - - return $sCriteriasResult; - } - - /** - * @param array $aThreads - * @return array - */ - private function threadArrayMap($aThreads) - { - $aNew = array(); - foreach ($aThreads as $mItem) - { - if (!\is_array($mItem)) - { - $aNew[] = $mItem; - } - else - { - $mMap = $this->threadArrayMap($mItem); - if (\is_array($mMap) && 0 < \count($mMap)) - { - $aNew = \array_merge($aNew, $mMap); - } - } - } - - return $aNew; - } - - /** - * @param array $aThreads - * - * @return array - */ - private function compileThreadArray($aThreads) - { - $aResult = array(); - foreach ($aThreads as $mItem) - { - if (\is_array($mItem)) - { - $aMap = $this->threadArrayMap($mItem); - if (\is_array($aMap)) - { - if (1 < \count($aMap)) - { - $aResult[] = $aMap; - } - else if (0 < \count($aMap)) - { - $aResult[] = $aMap[0]; - } - } - } - else - { - $aResult[] = $mItem; - } - } - - return $aResult; - } - - /** - * @param string $sFolderName - * @param string $sFolderHash - * @param array $aIndexOrUids - * @param \MailSo\Cache\CacheClient $oCacher - * @param bool $bCacheOnly = false - * - * @return array - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function MessageListThreadsMap($sFolderName, $sFolderHash, $aIndexOrUids, $oCacher, $bCacheOnly = false) - { - $iThreadLimit = \MailSo\Config::$LargeThreadLimit; - - $sSearchHash = ''; - if (0 < \MailSo\Config::$MessageListDateFilter) - { - $iD = \time() - 3600 * 24 * 30 * \MailSo\Config::$MessageListDateFilter; - $iTimeFilter = \gmmktime(1, 1, 1, \gmdate('n', $iD), 1, \gmdate('Y', $iD)); - - $sSearchHash .= ' SINCE '.\gmdate('j-M-Y', $iTimeFilter); - } - - if ('' === \trim($sSearchHash)) - { - $sSearchHash = 'ALL'; - } - - if ($oCacher && $oCacher->IsInited()) - { - $sSerializedHashKey = - 'ThreadsMapSorted/'.$sSearchHash.'/'. - 'Limit='.$iThreadLimit.'/'.$sFolderName.'/'.$sFolderHash; - - if ($this->oLogger) - { - $this->oLogger->Write($sSerializedHashKey); - } - - $sSerializedUids = $oCacher->Get($sSerializedHashKey); - if (!empty($sSerializedUids)) - { - $aSerializedUids = @\json_decode($sSerializedUids, true); - if (isset($aSerializedUids['ThreadsUids']) && \is_array($aSerializedUids['ThreadsUids'])) - { - if ($this->oLogger) - { - $this->oLogger->Write('Get Serialized Thread UIDS from cache ("'.$sFolderName.'" / '.$sSearchHash.') [count:'.\count($aSerializedUids['ThreadsUids']).']'); - } - - return $aSerializedUids['ThreadsUids']; - } - } - } - - if ($bCacheOnly) - { - return null; - } - - $this->oImapClient->FolderExamine($sFolderName); - - $aThreadUids = array(); - try - { - $aThreadUids = $this->oImapClient->MessageSimpleThread($sSearchHash); - } - catch (\MailSo\Imap\Exceptions\RuntimeException $oException) - { - unset($oException); - $aThreadUids = array(); - } - - $aResult = array(); - $aCompiledThreads = $this->compileThreadArray($aThreadUids); - - foreach ($aCompiledThreads as $mData) - { - if (\is_array($mData)) - { - foreach ($mData as $mSubData) - { - $aResult[(int) $mSubData] = - \array_diff($mData, array((int) $mSubData)); - } - } - else if (\is_int($mData) || \is_string($mData)) - { - $aResult[(int) $mData] = (int) $mData; - } - } - - $aParentsMap = array(); - foreach ($aIndexOrUids as $iUid) - { - if (isset($aResult[$iUid]) && \is_array($aResult[$iUid])) - { - foreach ($aResult[$iUid] as $iTempUid) - { - $aParentsMap[$iTempUid] = $iUid; - if (isset($aResult[$iTempUid])) - { - unset($aResult[$iTempUid]); - } - } - } - } - - $aSortedThreads = array(); - foreach ($aIndexOrUids as $iUid) - { - if (isset($aResult[$iUid])) - { - $aSortedThreads[$iUid] = $iUid; - } - } - - foreach ($aIndexOrUids as $iUid) - { - if (!isset($aSortedThreads[$iUid]) && - isset($aParentsMap[$iUid]) && - isset($aSortedThreads[$aParentsMap[$iUid]])) - { - if (!\is_array($aSortedThreads[$aParentsMap[$iUid]])) - { - $aSortedThreads[$aParentsMap[$iUid]] = array(); - } - - $aSortedThreads[$aParentsMap[$iUid]][] = $iUid; - } - } - - $aResult = $aSortedThreads; - unset($aParentsMap, $aSortedThreads); - - $aTemp = array(); - foreach ($aResult as $iUid => $mValue) - { - if (0 < $iThreadLimit && \is_array($mValue) && $iThreadLimit < \count($mValue)) - { - $aParts = \array_chunk($mValue, $iThreadLimit); - if (0 < count($aParts)) - { - foreach ($aParts as $iIndex => $aItem) - { - if (0 === $iIndex) - { - $aResult[$iUid] = $aItem; - } - else if (0 < $iIndex && \is_array($aItem)) - { - $mFirst = \array_shift($aItem); - if (!empty($mFirst)) - { - $aTemp[$mFirst] = 0 < \count($aItem) ? $aItem : $mFirst; - } - } - } - } - } - } - - foreach ($aTemp as $iUid => $mValue) - { - $aResult[$iUid] = $mValue; - } - - unset($aTemp); - - $aLastResult = array(); - foreach ($aIndexOrUids as $iUid) - { - if (isset($aResult[$iUid])) - { - $aLastResult[$iUid] = $aResult[$iUid]; - } - } - - $aResult = $aLastResult; - unset($aLastResult); - - if ($oCacher && $oCacher->IsInited() && !empty($sSerializedHashKey)) - { - $oCacher->Set($sSerializedHashKey, @\json_encode(array( - 'ThreadsUids' => $aResult - ))); - - if ($this->oLogger) - { - $this->oLogger->Write('Save Serialized Thread UIDS to cache ("'.$sFolderName.'" / '.$sSearchHash.') [count:'.\count($aResult).']'); - } - } - - return $aResult; - } - - /** - * @param \MailSo\Mail\MessageCollection &$oMessageCollection - * @param array $aRequestIndexOrUids - * @param bool $bIndexAsUid - * @param bool $bSimple = false - * - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function MessageListByRequestIndexOrUids(&$oMessageCollection, $aRequestIndexOrUids, $bIndexAsUid, $bSimple = false) - { - if (\is_array($aRequestIndexOrUids) && 0 < \count($aRequestIndexOrUids)) - { - $aFetchResponse = $this->oImapClient->Fetch(array( - \MailSo\Imap\Enumerations\FetchType::INDEX, - \MailSo\Imap\Enumerations\FetchType::UID, - \MailSo\Imap\Enumerations\FetchType::RFC822_SIZE, - \MailSo\Imap\Enumerations\FetchType::INTERNALDATE, - \MailSo\Imap\Enumerations\FetchType::FLAGS, - \MailSo\Imap\Enumerations\FetchType::BODYSTRUCTURE, - $bSimple ? - $this->getEnvelopeOrHeadersRequestStringForSimpleList() : - $this->getEnvelopeOrHeadersRequestString() - ), \MailSo\Base\Utils::PrepearFetchSequence($aRequestIndexOrUids), $bIndexAsUid); - - if (\is_array($aFetchResponse) && 0 < \count($aFetchResponse)) - { - $aFetchIndexArray = array(); - $oFetchResponseItem = null; - foreach ($aFetchResponse as /* @var $oFetchResponseItem \MailSo\Imap\FetchResponse */ &$oFetchResponseItem) - { - $aFetchIndexArray[($bIndexAsUid) - ? $oFetchResponseItem->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::UID) - : $oFetchResponseItem->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::INDEX)] =& $oFetchResponseItem; - - unset($oFetchResponseItem); - } - - foreach ($aRequestIndexOrUids as $iFUid) - { - if (isset($aFetchIndexArray[$iFUid])) - { - $oMessageCollection->Add( - Message::NewFetchResponseInstance( - $oMessageCollection->FolderName, $aFetchIndexArray[$iFUid])); - } - } - } - } - } - - /** - * @return bool - * - * @throws \MailSo\Net\Exceptions\Exception - */ - public function IsThreadsSupported() - { - return $this->oImapClient->IsSupported('THREAD=REFS') || - $this->oImapClient->IsSupported('THREAD=REFERENCES') || - $this->oImapClient->IsSupported('THREAD=ORDEREDSUBJECT'); - } - - /** - * @param string $sFolderName - * @param array $aUids - * - * @return \MailSo\Mail\MessageCollection - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function MessageListSimple($sFolderName, $aUids) - { - if (0 === \strlen($sFolderName) || !\MailSo\Base\Validator::NotEmptyArray($aUids)) - { - throw new \MailSo\Base\Exceptions\InvalidArgumentException(); - } - - $this->oImapClient->FolderExamine($sFolderName); - - $oMessageCollection = \MailSo\Mail\MessageCollection::NewInstance(); - $oMessageCollection->FolderName = $sFolderName; - - $this->MessageListByRequestIndexOrUids($oMessageCollection, $aUids, true, true); - - return $oMessageCollection->GetAsArray(); - } - - /** - * @param \MailSo\Cache\CacheClient|null $oCacher - * @param string $sSearch - * @param string $sFilter - * @param string $sFolderName - * @param string $sFolderHash - * @param bool $bUseSortIfSupported = false - * - * @return array - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function GetUids($oCacher, $sSearch, $sFilter, $sFolderName, $sFolderHash, $bUseSortIfSupported = false) - { - $aResultUids = false; - $bUidsFromCacher = false; - $bUseCacheAfterSearch = true; - - $sSerializedHash = ''; - $sSerializedLog = ''; - - $bUseSortIfSupported = $bUseSortIfSupported ? !!$this->oImapClient->IsSupported('SORT') : false; - - if (0 < \strlen($sSearch)) - { - $bUseSortIfSupported = false; - } - - $sSearchCriterias = $this->getImapSearchCriterias($sSearch, $sFilter, 0, $bUseCacheAfterSearch); - if ($bUseCacheAfterSearch && $oCacher && $oCacher->IsInited()) - { - $sSerializedHash = 'GetUids/'. - ($bUseSortIfSupported ? 'S': 'N').'/'. - $this->GenerateImapClientHash().'/'. - $sFolderName.'/'.$sSearchCriterias; - - $sSerializedLog = '"'.$sFolderName.'" / '.$sSearchCriterias.''; - - $sSerialized = $oCacher->Get($sSerializedHash); - if (!empty($sSerialized)) - { - $aSerialized = @\json_decode($sSerialized, true); - if (\is_array($aSerialized) && isset($aSerialized['FolderHash'], $aSerialized['Uids']) && - $sFolderHash === $aSerialized['FolderHash'] && - \is_array($aSerialized['Uids']) - ) - { - if ($this->oLogger) - { - $this->oLogger->Write('Get Serialized UIDS from cache ('.$sSerializedLog.') [count:'.\count($aSerialized['Uids']).']'); - } - - $aResultUids = $aSerialized['Uids']; - $bUidsFromCacher = true; - } - } - } - - if (!\is_array($aResultUids)) - { - $aResultUids = $bUseSortIfSupported ? - $this->oImapClient->MessageSimpleSort(array('REVERSE ARRIVAL'), $sSearchCriterias, true) : - $this->oImapClient->MessageSimpleSearch($sSearchCriterias, true, \MailSo\Base\Utils::IsAscii($sSearchCriterias) ? '' : 'UTF-8') - ; - - if (!$bUidsFromCacher && $bUseCacheAfterSearch && \is_array($aResultUids) && $oCacher && $oCacher->IsInited() && 0 < \strlen($sSerializedHash)) - { - $oCacher->Set($sSerializedHash, @\json_encode(array( - 'FolderHash' => $sFolderHash, - 'Uids' => $aResultUids - ))); - - if ($this->oLogger) - { - $this->oLogger->Write('Save Serialized UIDS to cache ('.$sSerializedLog.') [count:'.\count($aResultUids).']'); - } - } - } - - return \is_array($aResultUids) ? $aResultUids : array(); - } - - /** - * @param string $sFolderName - * @param int $iOffset = 0 - * @param int $iLimit = 10 - * @param string $sSearch = '' - * @param string $sPrevUidNext = '' - * @param \MailSo\Cache\CacheClient|null $oCacher = null - * @param bool $bUseSortIfSupported = false - * @param bool $bUseThreadSortIfSupported = false - * @param bool $bUseESearchOrESortRequest = false - * @param string $sThreadUid = '' - * @param string $sFilter = '' - * - * @return \MailSo\Mail\MessageCollection - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Imap\Exceptions\Exception - */ - public function MessageList($sFolderName, $iOffset = 0, $iLimit = 10, $sSearch = '', $sPrevUidNext = '', $oCacher = null, - $bUseSortIfSupported = false, $bUseThreadSortIfSupported = false, $sThreadUid = '', $sFilter = '') - { - $sFilter = \trim($sFilter); - $sSearch = \trim($sSearch); - if (!\MailSo\Base\Validator::RangeInt($iOffset, 0) || - !\MailSo\Base\Validator::RangeInt($iLimit, 0, 999)) - { - throw new \MailSo\Base\Exceptions\InvalidArgumentException(); - } - - $bUseFilter = '' !== $sFilter; - - $this->oImapClient->FolderSelect($sFolderName); - - $oMessageCollection = MessageCollection::NewInstance(); - $oMessageCollection->FolderName = $sFolderName; - $oMessageCollection->Offset = $iOffset; - $oMessageCollection->Limit = $iLimit; - $oMessageCollection->Search = $sSearch; - $oMessageCollection->ThreadUid = $sThreadUid; - $oMessageCollection->Filtered = '' !== \MailSo\Config::$MessageListPermanentFilter; - - $aUids = array(); - $mAllSortedUids = null; - $mAllThreads = null; - - $iThreadUid = empty($sThreadUid) ? 0 : (int) $sThreadUid; - - $iMessageRealCount = 0; - $iMessageUnseenCount = 0; - $sUidNext = '0'; - $sHighestModSeq = ''; - - $bUseSortIfSupported = $bUseSortIfSupported ? $this->oImapClient->IsSupported('SORT') : false; - - $bUseThreadSortIfSupported = $bUseThreadSortIfSupported ? - ($this->oImapClient->IsSupported('THREAD=REFS') || $this->oImapClient->IsSupported('THREAD=REFERENCES') || $this->oImapClient->IsSupported('THREAD=ORDEREDSUBJECT')) : false; - - if (!empty($sThreadUid) && !$bUseThreadSortIfSupported) - { - throw new \MailSo\Base\Exceptions\InvalidArgumentException(); - } - - if (!$oCacher || !($oCacher instanceof \MailSo\Cache\CacheClient)) - { - $oCacher = null; - } - - $this->initFolderValues($sFolderName, $iMessageRealCount, $iMessageUnseenCount, $sUidNext, $sHighestModSeq); - - if ($bUseFilter) - { - $iMessageUnseenCount = 0; - } - - $oMessageCollection->FolderHash = $this->GenerateFolderHash( - $sFolderName, $iMessageRealCount, $iMessageUnseenCount, $sUidNext, $sHighestModSeq); - - $oMessageCollection->UidNext = $sUidNext; - - if (empty($sThreadUid) && 0 < \strlen($sPrevUidNext) && 'INBOX' === $sFolderName) - { - $oMessageCollection->NewMessages = $this->getFolderNextMessageInformation( - $sFolderName, $sPrevUidNext, $sUidNext); - } - - $bSearch = false; - $bMessageListOptimization = 0 < \MailSo\Config::$MessageListCountLimitTrigger && - \MailSo\Config::$MessageListCountLimitTrigger < $iMessageRealCount; - - if ($bMessageListOptimization) - { - $bUseSortIfSupported = false; - $bUseThreadSortIfSupported = false; - } - - if (0 < $iMessageRealCount && !$bMessageListOptimization) - { - $mAllSortedUids = $this->GetUids($oCacher, '', $sFilter, - $oMessageCollection->FolderName, $oMessageCollection->FolderHash, $bUseSortIfSupported); - - $mAllThreads = $bUseThreadSortIfSupported ? $this->MessageListThreadsMap( - $oMessageCollection->FolderName, $oMessageCollection->FolderHash, $mAllSortedUids, $oCacher) : null; - - if ($bUseThreadSortIfSupported && 0 < $iThreadUid && \is_array($mAllThreads)) - { - $aUids = array(); - $iResultRootUid = 0; - - if (isset($mAllThreads[$iThreadUid])) - { - $iResultRootUid = $iThreadUid; - if (\is_array($mAllThreads[$iThreadUid])) - { - $aUids = $mAllThreads[$iThreadUid]; - } - } - else - { - foreach ($mAllThreads as $iRootUid => $mSubUids) - { - if (\is_array($mSubUids) && \in_array($iThreadUid, $mSubUids)) - { - $iResultRootUid = $iRootUid; - $aUids = $mSubUids; - continue; - } - } - } - - if (0 < $iResultRootUid && \in_array($iResultRootUid, $mAllSortedUids)) - { - \array_unshift($aUids, $iResultRootUid); - } - } - else if ($bUseThreadSortIfSupported && \is_array($mAllThreads)) - { - $aUids = \array_keys($mAllThreads); - } - else - { - $bUseThreadSortIfSupported = false; - $aUids = $mAllSortedUids; - } - - if (0 < \strlen($sSearch) && \is_array($aUids)) - { - $aSearchedUids = $this->GetUids($oCacher, $sSearch, $sFilter, - $oMessageCollection->FolderName, $oMessageCollection->FolderHash); - - if (\is_array($aSearchedUids) && 0 < \count($aSearchedUids)) - { - $aFlippedSearchedUids = \array_flip($aSearchedUids); - - $bSearch = true; - $aNewUids = array(); - - foreach ($aUids as $iUid) - { - if (isset($aFlippedSearchedUids[$iUid])) - { - $aNewUids[] = $iUid; - } - else if ($bUseThreadSortIfSupported && 0 === $iThreadUid && isset($mAllThreads[$iUid]) && \is_array($mAllThreads[$iUid])) - { - foreach ($mAllThreads[$iUid] as $iSubUid) - { - if (isset($aFlippedSearchedUids[$iSubUid])) - { - $aNewUids[] = $iUid; - continue; - } - } - } - } - - $aUids = \array_unique($aNewUids); - unset($aNewUids); - } - else - { - $aUids = array(); - } - } - - if (\is_array($aUids)) - { - $oMessageCollection->MessageCount = $iMessageRealCount; - $oMessageCollection->MessageUnseenCount = $iMessageUnseenCount; - $oMessageCollection->MessageResultCount = \count($aUids); - - if (0 < \count($aUids)) - { - $aRequestUids = \array_slice($aUids, $iOffset, $iLimit); - $this->MessageListByRequestIndexOrUids($oMessageCollection, $aRequestUids, true); - } - } - } - else if (0 < $iMessageRealCount) - { - if ($this->oLogger) - { - $this->oLogger->Write('List optimization (count: '.$iMessageRealCount. - ', limit:'.\MailSo\Config::$MessageListCountLimitTrigger.')'); - } - - $oMessageCollection->MessageCount = $iMessageRealCount; - $oMessageCollection->MessageUnseenCount = $iMessageUnseenCount; - - if (0 < \strlen($sSearch) || $bUseFilter) - { - $aUids = $this->GetUids($oCacher, $sSearch, $sFilter, - $oMessageCollection->FolderName, $oMessageCollection->FolderHash); - - if (0 < \count($aUids)) - { - $oMessageCollection->MessageResultCount = \count($aUids); - - $aRequestUids = \array_slice($aUids, $iOffset, $iLimit); - $this->MessageListByRequestIndexOrUids($oMessageCollection, $aRequestUids, true); - } - else - { - $oMessageCollection->MessageResultCount = 0; - } - } - else - { - $oMessageCollection->MessageResultCount = $iMessageRealCount; - - if (1 < $iMessageRealCount) - { - $aRequestIndexes = \array_slice(array_reverse(range(1, $iMessageRealCount)), $iOffset, $iLimit); - } - else - { - $aRequestIndexes = \array_slice(array(1), $iOffset, $iLimit); - } - - $this->MessageListByRequestIndexOrUids($oMessageCollection, $aRequestIndexes, false); - } - } - - if ($bUseThreadSortIfSupported && 0 === $iThreadUid && \is_array($mAllThreads) && 0 < \count($mAllThreads)) - { - $oMessageCollection->ForeachList(function (/* @var $oMessage \MailSo\Mail\Message */ $oMessage) use ($mAllThreads) { - - $iUid = $oMessage->Uid(); - if (isset($mAllThreads[$iUid]) && \is_array($mAllThreads[$iUid]) && 0 < \count($mAllThreads[$iUid])) - { - $aSubThreads = $mAllThreads[$iUid]; - \array_unshift($aSubThreads, $iUid); - - $oMessage->SetThreads(\array_map('trim', $aSubThreads)); - unset($aSubThreads); - } - }); - } - - return $oMessageCollection; - } - - /** - * @return array|false - */ - public function Quota() - { - return $this->oImapClient->Quota(); - } - - /** - * @param string $sFolderName - * @param string $sMessageId - * - * @return int|null - */ - public function FindMessageUidByMessageId($sFolderName, $sMessageId) - { - if (0 === \strlen($sMessageId)) - { - throw new \MailSo\Base\Exceptions\InvalidArgumentException(); - } - - $this->oImapClient->FolderExamine($sFolderName); - - $aUids = $this->oImapClient->MessageSimpleSearch( - 'HEADER Message-ID '.$sMessageId, true); - - return \is_array($aUids) && 1 === \count($aUids) && \is_numeric($aUids[0]) ? (int) $aUids[0] : null; - } - - /** - * @param array $aMailFoldersHelper - * @param int $iOptimizationLimit = 0 - * - * @return array - */ - public function folderListOptimization($aMailFoldersHelper, $iOptimizationLimit = 0) - { - // optimization - if (10 < $iOptimizationLimit && \is_array($aMailFoldersHelper) && $iOptimizationLimit < \count($aMailFoldersHelper)) - { - if ($this->oLogger) - { - $this->oLogger->Write('Start optimization (limit:'.$iOptimizationLimit.') for '.\count($aMailFoldersHelper).' folders'); - } - - $iForeachLimit = 1; - - $aFilteredNames = array( - 'inbox', - 'sent', 'send', 'outbox', 'sentmail', 'sendmail', - 'drafts', 'draft', - 'junk', 'spam', 'spambucket', - 'trash', 'bin', 'deleted', - 'archives', 'archive', 'allmail', 'all', - 'starred', 'flagged', 'important', - 'contacts', 'chats' - ); - - $aNewMailFoldersHelper = array(); - - $iCountLimit = $iForeachLimit; - - foreach ($aMailFoldersHelper as $iIndex => /* @var $oImapFolder \MailSo\Mail\Folder */ $oFolder) - { - // mandatory folders - if ($oFolder && \in_array(\str_replace(' ', '', \strtolower($oFolder->NameRaw())), $aFilteredNames)) - { - $aNewMailFoldersHelper[] = $oFolder; - $aMailFoldersHelper[$iIndex] = null; - } - } - - foreach ($aMailFoldersHelper as $iIndex => /* @var $oImapFolder \MailSo\Mail\Folder */ $oFolder) - { - // subscribed folders - if ($oFolder && $oFolder->IsSubscribed()) - { - $aNewMailFoldersHelper[] = $oFolder; - - $aMailFoldersHelper[$iIndex] = null; - $iCountLimit--; - } - - if (0 > $iCountLimit) - { - if ($iOptimizationLimit < \count($aNewMailFoldersHelper)) - { - break; - } - else - { - $iCountLimit = $iForeachLimit; - } - } - } - - $iCountLimit = $iForeachLimit; - if ($iOptimizationLimit >= \count($aNewMailFoldersHelper)) - { - // name filter - foreach ($aMailFoldersHelper as $iIndex => /* @var $oImapFolder \MailSo\Mail\Folder */ $oFolder) - { - if ($oFolder && !\preg_match('/[{}\[\]]/', $oFolder->NameRaw())) - { - $aNewMailFoldersHelper[] = $oFolder; - - $aMailFoldersHelper[$iIndex] = null; - $iCountLimit--; - } - - if (0 > $iCountLimit) - { - if ($iOptimizationLimit < \count($aNewMailFoldersHelper)) - { - break; - } - else - { - $iCountLimit = $iForeachLimit; - } - } - } - } - - $iCountLimit = $iForeachLimit; - if ($iOptimizationLimit >= \count($aNewMailFoldersHelper)) - { - // other - foreach ($aMailFoldersHelper as $iIndex => /* @var $oImapFolder \MailSo\Mail\Folder */ $oFolder) - { - if ($oFolder) - { - $aNewMailFoldersHelper[] = $oFolder; - - $aMailFoldersHelper[$iIndex] = null; - $iCountLimit--; - } - - if (0 > $iCountLimit) - { - if ($iOptimizationLimit < \count($aNewMailFoldersHelper)) - { - break; - } - else - { - $iCountLimit = $iForeachLimit; - } - } - } - } - - $aMailFoldersHelper = $aNewMailFoldersHelper; - - if ($this->oLogger) - { - $this->oLogger->Write('Result optimization: '.\count($aMailFoldersHelper).' folders'); - } - } - - return $aMailFoldersHelper; - } - - /** - * @param string $sParent = '' - * @param string $sListPattern = '*' - * @param bool $bUseListSubscribeStatus = false - * @param int $iOptimizationLimit = 0 - * - * @return \MailSo\Mail\FolderCollection|false - */ - public function Folders($sParent = '', $sListPattern = '*', $bUseListSubscribeStatus = true, $iOptimizationLimit = 0) - { - $oFolderCollection = false; - - $aSubscribedFolders = null; - if ($bUseListSubscribeStatus) - { - try - { - $aSubscribedFolders = $this->oImapClient->FolderSubscribeList($sParent, $sListPattern); - } - catch (\Exception $oException) - { - unset($oException); - } - } - - $aImapSubscribedFoldersHelper = null; - if (\is_array($aSubscribedFolders)) - { - $aImapSubscribedFoldersHelper = array(); - foreach ($aSubscribedFolders as /* @var $oImapFolder \MailSo\Imap\Folder */ $oImapFolder) - { - $aImapSubscribedFoldersHelper[] = $oImapFolder->FullNameRaw(); - } - } - - $aFolders = $this->oImapClient->FolderList($sParent, $sListPattern); - - $bOptimized = false; - $aMailFoldersHelper = null; - - if (\is_array($aFolders)) - { - $aMailFoldersHelper = array(); - - foreach ($aFolders as /* @var $oImapFolder \MailSo\Imap\Folder */ $oImapFolder) - { - $aMailFoldersHelper[] = Folder::NewInstance($oImapFolder, - (null === $aImapSubscribedFoldersHelper || \in_array($oImapFolder->FullNameRaw(), $aImapSubscribedFoldersHelper)) || - $oImapFolder->IsInbox() - ); - } - - $iCount = \count($aMailFoldersHelper); - $aMailFoldersHelper = $this->folderListOptimization($aMailFoldersHelper, $iOptimizationLimit); - - $bOptimized = $iCount !== \count($aMailFoldersHelper); - } - - if (\is_array($aMailFoldersHelper)) - { - $oFolderCollection = FolderCollection::NewInstance(); - $oFolderCollection->InitByUnsortedMailFolderArray($aMailFoldersHelper); - - $oFolderCollection->Optimized = $bOptimized; - } - - if ($oFolderCollection) - { - $oFolderCollection->SortByCallback(function ($oFolderA, $oFolderB) { - $sA = \strtoupper($oFolderA->FullNameRaw()); - $sB = \strtoupper($oFolderB->FullNameRaw()); - switch (true) - { - case 'INBOX' === $sA: - return -1; - case 'INBOX' === $sB: - return 1; - case '[GMAIL]' === $sA: - return -1; - case '[GMAIL]' === $sB: - return 1; - } - - return \strnatcasecmp($oFolderA->FullName(), $oFolderB->FullName()); - }); - - $oNamespace = $this->oImapClient->GetNamespace(); - if ($oNamespace) - { - $oFolderCollection->SetNamespace($oNamespace->GetPersonalNamespace()); - } - - $oFolderCollection->IsThreadsSupported = $this->IsThreadsSupported(); - } - - return $oFolderCollection; - } - - /** - * @param string $sFolderNameInUtf8 - * @param string $sFolderParentFullNameRaw = '' - * @param bool $bSubscribeOnCreation = true - * @param string $sDelimiter = '' - * - * @return \MailSo\Mail\MailClient - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - */ - public function FolderCreate($sFolderNameInUtf8, $sFolderParentFullNameRaw = '', $bSubscribeOnCreation = true, $sDelimiter = '') - { - if (!\MailSo\Base\Validator::NotEmptyString($sFolderNameInUtf8, true) || - !\is_string($sFolderParentFullNameRaw)) - { - throw new \MailSo\Base\Exceptions\InvalidArgumentException(); - } - - $sFolderNameInUtf8 = \trim($sFolderNameInUtf8); - - if (0 === \strlen($sDelimiter) || 0 < \strlen(\trim($sFolderParentFullNameRaw))) - { - $aFolders = $this->oImapClient->FolderList('', 0 === \strlen(\trim($sFolderParentFullNameRaw)) ? 'INBOX' : $sFolderParentFullNameRaw); - if (!\is_array($aFolders) || !isset($aFolders[0])) - { - // TODO - throw new \MailSo\Mail\Exceptions\RuntimeException( - 0 === \strlen(trim($sFolderParentFullNameRaw)) - ? 'Cannot get folder delimiter' - : 'Cannot create folder in non-existen parent folder'); - } - - $sDelimiter = $aFolders[0]->Delimiter(); - if (0 < \strlen($sDelimiter) && 0 < \strlen(\trim($sFolderParentFullNameRaw))) - { - $sFolderParentFullNameRaw .= $sDelimiter; - } - } - - $sFullNameRawToCreate = \MailSo\Base\Utils::ConvertEncoding($sFolderNameInUtf8, - \MailSo\Base\Enumerations\Charset::UTF_8, - \MailSo\Base\Enumerations\Charset::UTF_7_IMAP); - - if (0 < \strlen($sDelimiter) && false !== \strpos($sFullNameRawToCreate, $sDelimiter)) - { - // TODO - throw new \MailSo\Mail\Exceptions\RuntimeException( - 'New folder name contains delimiter'); - } - - $sFullNameRawToCreate = $sFolderParentFullNameRaw.$sFullNameRawToCreate; - - $this->oImapClient->FolderCreate($sFullNameRawToCreate); - - if ($bSubscribeOnCreation) - { - $this->oImapClient->FolderSubscribe($sFullNameRawToCreate); - } - - return $this; - } - - /** - * @param string $sPrevFolderFullNameRaw - * @param string $sNextFolderFullNameInUtf - * @param bool $bSubscribeOnMove = true - * - * @return \MailSo\Mail\MailClient - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - */ - public function FolderMove($sPrevFolderFullNameRaw, $sNextFolderFullNameInUtf, $bSubscribeOnMove = true) - { - return $this->folderModify($sPrevFolderFullNameRaw, $sNextFolderFullNameInUtf, false, $bSubscribeOnMove); - } - - /** - * @param string $sPrevFolderFullNameRaw - * @param string $sNewTopFolderNameInUtf - * @param bool $bSubscribeOnRename = true - * - * @return \MailSo\Mail\MailClient - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - */ - public function FolderRename($sPrevFolderFullNameRaw, $sNewTopFolderNameInUtf, $bSubscribeOnRename = true) - { - return $this->folderModify($sPrevFolderFullNameRaw, $sNewTopFolderNameInUtf, true, $bSubscribeOnRename); - } - - /** - * @param string $sPrevFolderFullNameRaw - * @param string $sNextFolderNameInUtf - * @param bool $bRenameOrMove - * @param bool $bSubscribeOnModify - * - * @return \MailSo\Mail\MailClient - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - */ - public function folderModify($sPrevFolderFullNameRaw, $sNextFolderNameInUtf, $bRenameOrMove, $bSubscribeOnModify) - { - if (0 === \strlen($sPrevFolderFullNameRaw) || 0 === \strlen($sNextFolderNameInUtf)) - { - throw new \MailSo\Base\Exceptions\InvalidArgumentException(); - } - - $aFolders = $this->oImapClient->FolderList('', $sPrevFolderFullNameRaw); - if (!\is_array($aFolders) || !isset($aFolders[0])) - { - // TODO - throw new \MailSo\Mail\Exceptions\RuntimeException('Cannot rename non-existen folder'); - } - - $sDelimiter = $aFolders[0]->Delimiter(); - $iLast = \strrpos($sPrevFolderFullNameRaw, $sDelimiter); - - $mSubscribeFolders = null; - if ($bSubscribeOnModify) - { - $mSubscribeFolders = $this->oImapClient->FolderSubscribeList($sPrevFolderFullNameRaw, '*'); - if (\is_array($mSubscribeFolders) && 0 < count($mSubscribeFolders)) - { - foreach ($mSubscribeFolders as /* @var $oFolder \MailSo\Imap\Folder */ $oFolder) - { - $this->oImapClient->FolderUnSubscribe($oFolder->FullNameRaw()); - } - } - } - - $sNewFolderFullNameRaw = \MailSo\Base\Utils::ConvertEncoding($sNextFolderNameInUtf, - \MailSo\Base\Enumerations\Charset::UTF_8, - \MailSo\Base\Enumerations\Charset::UTF_7_IMAP); - - if($bRenameOrMove) - { - if (0 < \strlen($sDelimiter) && false !== \strpos($sNewFolderFullNameRaw, $sDelimiter)) - { - // TODO - throw new \MailSo\Mail\Exceptions\RuntimeException('New folder name contains delimiter'); - } - - $sFolderParentFullNameRaw = false === $iLast ? '' : \substr($sPrevFolderFullNameRaw, 0, $iLast + 1); - $sNewFolderFullNameRaw = $sFolderParentFullNameRaw.$sNewFolderFullNameRaw; - } - - $this->oImapClient->FolderRename($sPrevFolderFullNameRaw, $sNewFolderFullNameRaw); - - if (\is_array($mSubscribeFolders) && 0 < count($mSubscribeFolders)) - { - foreach ($mSubscribeFolders as /* @var $oFolder \MailSo\Imap\Folder */ $oFolder) - { - $sFolderFullNameRawForResubscrine = $oFolder->FullNameRaw(); - if (0 === \strpos($sFolderFullNameRawForResubscrine, $sPrevFolderFullNameRaw)) - { - $sNewFolderFullNameRawForResubscrine = $sNewFolderFullNameRaw. - \substr($sFolderFullNameRawForResubscrine, \strlen($sPrevFolderFullNameRaw)); - - $this->oImapClient->FolderSubscribe($sNewFolderFullNameRawForResubscrine); - } - } - } - - return $this; - } - - /** - * @param string $sFolderFullNameRaw - * @param bool $bUnsubscribeOnDeletion = true - * - * @return \MailSo\Mail\MailClient - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Mail\Exceptions\RuntimeException - */ - public function FolderDelete($sFolderFullNameRaw, $bUnsubscribeOnDeletion = true) - { - if (0 === \strlen($sFolderFullNameRaw) || 'INBOX' === $sFolderFullNameRaw) - { - throw new \MailSo\Base\Exceptions\InvalidArgumentException(); - } - - $this->oImapClient->FolderExamine($sFolderFullNameRaw); - - $aIndexOrUids = $this->oImapClient->MessageSimpleSearch('ALL'); - if (0 < \count($aIndexOrUids)) - { - throw new \MailSo\Mail\Exceptions\NonEmptyFolder(); - } - - $this->oImapClient->FolderExamine('INBOX'); - - if ($bUnsubscribeOnDeletion) - { - $this->oImapClient->FolderUnSubscribe($sFolderFullNameRaw); - } - - $this->oImapClient->FolderDelete($sFolderFullNameRaw); - - return $this; - } - - /** - * @param string $sFolderFullNameRaw - * - * @return \MailSo\Mail\MailClient - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - */ - public function FolderClear($sFolderFullNameRaw) - { - $this->oImapClient->FolderSelect($sFolderFullNameRaw); - - $oFolderInformation = $this->oImapClient->FolderCurrentInformation(); - if ($oFolderInformation && $oFolderInformation->Exists && 0 < $oFolderInformation->Exists) // STATUS? - { - $this->oImapClient->MessageStoreFlag('1:*', false, - array(\MailSo\Imap\Enumerations\MessageFlag::DELETED), - \MailSo\Imap\Enumerations\StoreAction::ADD_FLAGS_SILENT - ); - - $this->oImapClient->MessageExpunge(); - } - - return $this; - } - - /** - * @param string $sFolderFullNameRaw - * @param bool $bSubscribe - * - * @return \MailSo\Mail\MailClient - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - */ - public function FolderSubscribe($sFolderFullNameRaw, $bSubscribe) - { - if (0 === \strlen($sFolderFullNameRaw)) - { - throw new \MailSo\Base\Exceptions\InvalidArgumentException(); - } - - $this->oImapClient->{($bSubscribe) ? 'FolderSubscribe' : 'FolderUnSubscribe'}($sFolderFullNameRaw); - - return $this; - } - - /** - * @param \MailSo\Log\Logger $oLogger - * - * @return \MailSo\Mail\MailClient - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - */ - public function SetLogger($oLogger) - { - if (!($oLogger instanceof \MailSo\Log\Logger)) - { - throw new \MailSo\Base\Exceptions\InvalidArgumentException(); - } - - $this->oLogger = $oLogger; - $this->oImapClient->SetLogger($this->oLogger); - - return $this; - } -} +oLogger = null; + + $this->oImapClient = \MailSo\Imap\ImapClient::NewInstance(); + $this->oImapClient->SetTimeOuts(10, \MailSo\Config::$ImapTimeout); + } + + /** + * @return \MailSo\Mail\MailClient + */ + public static function NewInstance() + { + return new self(); + } + + /** + * @return \MailSo\Imap\ImapClient + */ + public function ImapClient() + { + return $this->oImapClient; + } + + /** + * @param string $sServerName + * @param int $iPort = 143 + * @param int $iSecurityType = \MailSo\Net\Enumerations\ConnectionSecurityType::AUTO_DETECT + * @param bool $bVerifySsl = false + * + * @return \MailSo\Mail\MailClient + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function Connect($sServerName, $iPort = 143, + $iSecurityType = \MailSo\Net\Enumerations\ConnectionSecurityType::AUTO_DETECT, $bVerifySsl = false) + { + $this->oImapClient->Connect($sServerName, $iPort, $iSecurityType, $bVerifySsl); + return $this; + } + + /** + * @param string $sLogin + * @param string $sPassword + * @param string $sProxyAuthUser = '' + * @param bool $bUseAuthPlainIfSupported = true + * @param bool $bUseAuthCramMd5IfSupported = true + * + * @return \MailSo\Mail\MailClient + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\LoginException + */ + public function Login($sLogin, $sPassword, $sProxyAuthUser = '', + $bUseAuthPlainIfSupported = true, $bUseAuthCramMd5IfSupported = true) + { + $this->oImapClient->Login($sLogin, $sPassword, $sProxyAuthUser, $bUseAuthPlainIfSupported, $bUseAuthCramMd5IfSupported); + return $this; + } + + /** + * @param string $sXOAuth2Token + * + * @return \MailSo\Mail\MailClient + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\LoginException + */ + public function LoginWithXOauth2($sXOAuth2Token) + { + $this->oImapClient->LoginWithXOauth2($sXOAuth2Token); + return $this; + } + + /** + * @return \MailSo\Mail\MailClient + * + * @throws \MailSo\Net\Exceptions\Exception + */ + public function Logout() + { + $this->oImapClient->Logout(); + return $this; + } + + /** + * @return \MailSo\Mail\MailClient + * + * @throws \MailSo\Net\Exceptions\Exception + */ + public function Disconnect() + { + $this->oImapClient->Disconnect(); + return $this; + } + + /** + * @return \MailSo\Mail\MailClient + * + * @throws \MailSo\Net\Exceptions\Exception + */ + public function LogoutAndDisconnect() + { + return $this->Logout()->Disconnect(); + } + + /** + * @return bool + */ + public function IsConnected() + { + return $this->oImapClient->IsConnected(); + } + + /** + * @return bool + */ + public function IsLoggined() + { + return $this->oImapClient->IsLoggined(); + } + + /** + * @return string + */ + private function getEnvelopeOrHeadersRequestStringForSimpleList() + { + return \MailSo\Imap\Enumerations\FetchType::BuildBodyCustomHeaderRequest(array( + \MailSo\Mime\Enumerations\Header::RETURN_PATH, + \MailSo\Mime\Enumerations\Header::RECEIVED, + \MailSo\Mime\Enumerations\Header::MIME_VERSION, + \MailSo\Mime\Enumerations\Header::FROM_, + \MailSo\Mime\Enumerations\Header::TO_, + \MailSo\Mime\Enumerations\Header::CC, + \MailSo\Mime\Enumerations\Header::SENDER, + \MailSo\Mime\Enumerations\Header::REPLY_TO, + \MailSo\Mime\Enumerations\Header::DATE, + \MailSo\Mime\Enumerations\Header::SUBJECT, + \MailSo\Mime\Enumerations\Header::CONTENT_TYPE, + \MailSo\Mime\Enumerations\Header::LIST_UNSUBSCRIBE, + ), true); + } + + /** + * @return string + */ + private function getEnvelopeOrHeadersRequestString() + { + if (\MailSo\Config::$MessageAllHeaders) + { + return \MailSo\Imap\Enumerations\FetchType::BODY_HEADER_PEEK; + } + + return \MailSo\Imap\Enumerations\FetchType::BuildBodyCustomHeaderRequest(array( + \MailSo\Mime\Enumerations\Header::RETURN_PATH, + \MailSo\Mime\Enumerations\Header::RECEIVED, + \MailSo\Mime\Enumerations\Header::MIME_VERSION, + \MailSo\Mime\Enumerations\Header::MESSAGE_ID, + \MailSo\Mime\Enumerations\Header::CONTENT_TYPE, + \MailSo\Mime\Enumerations\Header::FROM_, + \MailSo\Mime\Enumerations\Header::TO_, + \MailSo\Mime\Enumerations\Header::CC, + \MailSo\Mime\Enumerations\Header::BCC, + \MailSo\Mime\Enumerations\Header::SENDER, + \MailSo\Mime\Enumerations\Header::REPLY_TO, + \MailSo\Mime\Enumerations\Header::DELIVERED_TO, + \MailSo\Mime\Enumerations\Header::IN_REPLY_TO, + \MailSo\Mime\Enumerations\Header::REFERENCES, + \MailSo\Mime\Enumerations\Header::DATE, + \MailSo\Mime\Enumerations\Header::SUBJECT, + \MailSo\Mime\Enumerations\Header::SENSITIVITY, + \MailSo\Mime\Enumerations\Header::X_MSMAIL_PRIORITY, + \MailSo\Mime\Enumerations\Header::IMPORTANCE, + \MailSo\Mime\Enumerations\Header::X_PRIORITY, + \MailSo\Mime\Enumerations\Header::X_DRAFT_INFO, + \MailSo\Mime\Enumerations\Header::RETURN_RECEIPT_TO, + \MailSo\Mime\Enumerations\Header::DISPOSITION_NOTIFICATION_TO, + \MailSo\Mime\Enumerations\Header::X_CONFIRM_READING_TO, + \MailSo\Mime\Enumerations\Header::AUTHENTICATION_RESULTS, + \MailSo\Mime\Enumerations\Header::X_DKIM_AUTHENTICATION_RESULTS, + \MailSo\Mime\Enumerations\Header::LIST_UNSUBSCRIBE, + ), true); +// +// return \MailSo\Imap\Enumerations\FetchType::ENVELOPE; + } + + /** + * @param string $sFolderName + * @param string $sMessageFlag + * @param bool $bSetAction = true + * @param bool $sSkipUnsupportedFlag = false + * @param array $aCustomUids = null + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + * @throws \MailSo\Mail\Exceptions\Exception + */ + public function MessageSetFlagToAll($sFolderName, $sMessageFlag, $bSetAction = true, $sSkipUnsupportedFlag = false, $aCustomUids = null) + { + $this->oImapClient->FolderSelect($sFolderName); + + $oFolderInfo = $this->oImapClient->FolderCurrentInformation(); + if (!$oFolderInfo || !$oFolderInfo->IsFlagSupported($sMessageFlag)) + { + if (!$sSkipUnsupportedFlag) + { + throw new \MailSo\Mail\Exceptions\RuntimeException('Message flag "'.$sMessageFlag.'" is not supported.'); + } + } + + if ($oFolderInfo && 0 < $oFolderInfo->Exists) + { + $sStoreAction = $bSetAction + ? \MailSo\Imap\Enumerations\StoreAction::ADD_FLAGS_SILENT + : \MailSo\Imap\Enumerations\StoreAction::REMOVE_FLAGS_SILENT + ; + + if (is_array($aCustomUids)) + { + if (0 < count($aCustomUids)) + { + $this->oImapClient->MessageStoreFlag(implode(',', $aCustomUids), true, array($sMessageFlag), $sStoreAction); + } + } + else + { + $this->oImapClient->MessageStoreFlag('1:*', false, array($sMessageFlag), $sStoreAction); + } + } + } + + /** + * @param string $sFolderName + * @param array $aIndexRange + * @param bool $bIndexIsUid + * @param string $sMessageFlag + * @param bool $bSetAction = true + * @param bool $sSkipUnsupportedFlag = false + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + * @throws \MailSo\Mail\Exceptions\Exception + */ + public function MessageSetFlag($sFolderName, $aIndexRange, $bIndexIsUid, $sMessageFlag, $bSetAction = true, $sSkipUnsupportedFlag = false) + { + $this->oImapClient->FolderSelect($sFolderName); + + $oFolderInfo = $this->oImapClient->FolderCurrentInformation(); + if (!$oFolderInfo || !$oFolderInfo->IsFlagSupported($sMessageFlag)) + { + if (!$sSkipUnsupportedFlag) + { + throw new \MailSo\Mail\Exceptions\RuntimeException('Message flag "'.$sMessageFlag.'" is not supported.'); + } + } + else + { + $sStoreAction = $bSetAction + ? \MailSo\Imap\Enumerations\StoreAction::ADD_FLAGS_SILENT + : \MailSo\Imap\Enumerations\StoreAction::REMOVE_FLAGS_SILENT + ; + + $this->oImapClient->MessageStoreFlag(\MailSo\Base\Utils::PrepearFetchSequence($aIndexRange), + $bIndexIsUid, array($sMessageFlag), $sStoreAction); + } + } + + /** + * @param string $sFolderName + * @param array $aIndexRange + * @param bool $bIndexIsUid + * @param bool $bSetAction = true + * @param bool $sSkipUnsupportedFlag = false + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function MessageSetFlagged($sFolderName, $aIndexRange, $bIndexIsUid, $bSetAction = true, $sSkipUnsupportedFlag = false) + { + $this->MessageSetFlag($sFolderName, $aIndexRange, $bIndexIsUid, + \MailSo\Imap\Enumerations\MessageFlag::FLAGGED, $bSetAction, $sSkipUnsupportedFlag); + } + + /** + * @param string $sFolderName + * @param bool $bSetAction = true + * @param array $aCustomUids = null + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function MessageSetSeenToAll($sFolderName, $bSetAction = true, $aCustomUids = null) + { + $this->MessageSetFlagToAll($sFolderName, \MailSo\Imap\Enumerations\MessageFlag::SEEN, $bSetAction, true, $aCustomUids); + } + + /** + * @param string $sFolderName + * @param array $aIndexRange + * @param bool $bIndexIsUid + * @param bool $bSetAction = true + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function MessageSetSeen($sFolderName, $aIndexRange, $bIndexIsUid, $bSetAction = true) + { + $this->MessageSetFlag($sFolderName, $aIndexRange, $bIndexIsUid, + \MailSo\Imap\Enumerations\MessageFlag::SEEN, $bSetAction, true); + } + + /** + * @param string $sFolderName + * @param int $iIndex + * @param bool $bIndexIsUid = true + * @param \MailSo\Cache\CacheClient $oCacher = null + * @param int $iBodyTextLimit = null + * + * @return \MailSo\Mail\Message|false + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function Message($sFolderName, $iIndex, $bIndexIsUid = true, $oCacher = null, $iBodyTextLimit = null) + { + if (!\MailSo\Base\Validator::RangeInt($iIndex, 1)) + { + throw new \MailSo\Base\Exceptions\InvalidArgumentException(); + } + + $this->oImapClient->FolderSelect($sFolderName); + + $oBodyStructure = null; + $oMessage = false; + + $aBodyPeekMimeIndexes = array(); + $aSignatureMimeIndexes = array(); + + $aFetchResponse = $this->oImapClient->Fetch(array(\MailSo\Imap\Enumerations\FetchType::BODYSTRUCTURE), $iIndex, $bIndexIsUid); + if (0 < \count($aFetchResponse) && isset($aFetchResponse[0])) + { + $oBodyStructure = $aFetchResponse[0]->GetFetchBodyStructure(); + if ($oBodyStructure) + { + $aTextParts = $oBodyStructure->SearchHtmlOrPlainParts(); + if (is_array($aTextParts) && 0 < \count($aTextParts)) + { + foreach ($aTextParts as $oPart) + { + $aBodyPeekMimeIndexes[] = array($oPart->PartID(), $oPart->Size()); + } + } + + $aSignatureParts = $oBodyStructure->SearchByContentType('application/pgp-signature'); + if (is_array($aSignatureParts) && 0 < \count($aSignatureParts)) + { + foreach ($aSignatureParts as $oPart) + { + $aSignatureMimeIndexes[] = $oPart->PartID(); + } + } + } + } + + $aFetchItems = array( + \MailSo\Imap\Enumerations\FetchType::INDEX, + \MailSo\Imap\Enumerations\FetchType::UID, + \MailSo\Imap\Enumerations\FetchType::RFC822_SIZE, + \MailSo\Imap\Enumerations\FetchType::INTERNALDATE, + \MailSo\Imap\Enumerations\FetchType::FLAGS, + $this->getEnvelopeOrHeadersRequestString() + ); + + if (0 < \count($aBodyPeekMimeIndexes)) + { + foreach ($aBodyPeekMimeIndexes as $aTextMimeData) + { + $sLine = \MailSo\Imap\Enumerations\FetchType::BODY_PEEK.'['.$aTextMimeData[0].']'; + if (\is_numeric($iBodyTextLimit) && 0 < $iBodyTextLimit && $iBodyTextLimit < $aTextMimeData[1]) + { + $sLine .= '<0.'.((int) $iBodyTextLimit).'>'; + } + + $aFetchItems[] = $sLine; + } + } + + if (0 < \count($aSignatureMimeIndexes)) + { + foreach ($aSignatureMimeIndexes as $sTextMimeIndex) + { + $aFetchItems[] = \MailSo\Imap\Enumerations\FetchType::BODY_PEEK.'['.$sTextMimeIndex.']'; + } + } + + if (!$oBodyStructure) + { + $aFetchItems[] = \MailSo\Imap\Enumerations\FetchType::BODYSTRUCTURE; + } + + $aFetchResponse = $this->oImapClient->Fetch($aFetchItems, $iIndex, $bIndexIsUid); + if (0 < \count($aFetchResponse)) + { + $oMessage = \MailSo\Mail\Message::NewFetchResponseInstance( + $sFolderName, $aFetchResponse[0], $oBodyStructure); + } + + return $oMessage; + } + + /** + * @param mixed $mCallback + * @param string $sFolderName + * @param int $iIndex + * @param bool $bIndexIsUid = true, + * @param string $sMimeIndex = '' + * + * @return bool + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function MessageMimeStream($mCallback, $sFolderName, $iIndex, $bIndexIsUid = true, $sMimeIndex = '') + { + if (!is_callable($mCallback)) + { + throw new \MailSo\Base\Exceptions\InvalidArgumentException(); + } + + $this->oImapClient->FolderSelect($sFolderName); + + $sFileName = ''; + $sContentType = ''; + $sMailEncodingName = ''; + + $sMimeIndex = trim($sMimeIndex); + $aFetchResponse = $this->oImapClient->Fetch(array( + 0 === \strlen($sMimeIndex) + ? \MailSo\Imap\Enumerations\FetchType::BODY_HEADER_PEEK + : \MailSo\Imap\Enumerations\FetchType::BODY_PEEK.'['.$sMimeIndex.'.MIME]' + ), $iIndex, $bIndexIsUid); + + if (0 < \count($aFetchResponse)) + { + $sMime = $aFetchResponse[0]->GetFetchValue( + 0 === \strlen($sMimeIndex) + ? \MailSo\Imap\Enumerations\FetchType::BODY_HEADER + : \MailSo\Imap\Enumerations\FetchType::BODY.'['.$sMimeIndex.'.MIME]' + ); + + if (0 < \strlen($sMime)) + { + $oHeaders = \MailSo\Mime\HeaderCollection::NewInstance()->Parse($sMime); + + if (0 < \strlen($sMimeIndex)) + { + $sFileName = $oHeaders->ParameterValue( + \MailSo\Mime\Enumerations\Header::CONTENT_DISPOSITION, + \MailSo\Mime\Enumerations\Parameter::FILENAME); + + if (0 === \strlen($sFileName)) + { + $sFileName = $oHeaders->ParameterValue( + \MailSo\Mime\Enumerations\Header::CONTENT_TYPE, + \MailSo\Mime\Enumerations\Parameter::NAME); + } + + $sMailEncodingName = $oHeaders->ValueByName( + \MailSo\Mime\Enumerations\Header::CONTENT_TRANSFER_ENCODING); + + $sContentType = $oHeaders->ValueByName( + \MailSo\Mime\Enumerations\Header::CONTENT_TYPE); + } + else + { + $sSubject = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::SUBJECT); + + $sFileName = 0 === \strlen($sSubject) ? (string) $iIndex : $sSubject; + $sFileName .= '.eml'; + + $sContentType = 'message/rfc822'; + } + } + } + + $aFetchResponse = $this->oImapClient->Fetch(array( + array(\MailSo\Imap\Enumerations\FetchType::BODY_PEEK.'['.$sMimeIndex.']', + function ($sParent, $sLiteralAtomUpperCase, $rImapLiteralStream) use ($mCallback, $sMimeIndex, $sMailEncodingName, $sContentType, $sFileName) + { + if (0 < \strlen($sLiteralAtomUpperCase)) + { + if (is_resource($rImapLiteralStream) && 'FETCH' === $sParent) + { + $rMessageMimeIndexStream = (0 === \strlen($sMailEncodingName)) + ? $rImapLiteralStream + : \MailSo\Base\StreamWrappers\Binary::CreateStream($rImapLiteralStream, + \MailSo\Base\StreamWrappers\Binary::GetInlineDecodeOrEncodeFunctionName( + $sMailEncodingName, true)); + + \call_user_func($mCallback, $rMessageMimeIndexStream, $sContentType, $sFileName, $sMimeIndex); + } + } + } + )), $iIndex, $bIndexIsUid); + + return ($aFetchResponse && 1 === \count($aFetchResponse)); + } + + /** + * @param string $sFolder + * @param array $aIndexRange + * @param bool $bIndexIsUid + * @param bool $bUseExpunge = true + * @param bool $bExpungeAll = false + * + * @return \MailSo\Mail\MailClient + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function MessageDelete($sFolder, $aIndexRange, $bIndexIsUid, $bUseExpunge = true, $bExpungeAll = false) + { + if (0 === \strlen($sFolder) || !\is_array($aIndexRange) || 0 === \count($aIndexRange)) + { + throw new \MailSo\Base\Exceptions\InvalidArgumentException(); + } + + $this->oImapClient->FolderSelect($sFolder); + + $sIndexRange = \MailSo\Base\Utils::PrepearFetchSequence($aIndexRange); + + $this->oImapClient->MessageStoreFlag($sIndexRange, $bIndexIsUid, + array(\MailSo\Imap\Enumerations\MessageFlag::DELETED), + \MailSo\Imap\Enumerations\StoreAction::ADD_FLAGS_SILENT + ); + + if ($bUseExpunge) + { + $this->oImapClient->MessageExpunge($bIndexIsUid ? $sIndexRange : '', $bIndexIsUid, $bExpungeAll); + } + + return $this; + } + + /** + * @param string $sFromFolder + * @param string $sToFolder + * @param array $aIndexRange + * @param bool $bIndexIsUid + * @param bool $bUseMoveSupported = false + * @param bool $bExpungeAll = false + * + * @return \MailSo\Mail\MailClient + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function MessageMove($sFromFolder, $sToFolder, $aIndexRange, $bIndexIsUid, $bUseMoveSupported = false, $bExpungeAll = false) + { + if (0 === \strlen($sFromFolder) || 0 === \strlen($sToFolder) || + !\is_array($aIndexRange) || 0 === \count($aIndexRange)) + { + throw new \MailSo\Base\Exceptions\InvalidArgumentException(); + } + + $this->oImapClient->FolderSelect($sFromFolder); + + if ($bUseMoveSupported && $this->oImapClient->IsSupported('MOVE')) + { + $this->oImapClient->MessageMove($sToFolder, + \MailSo\Base\Utils::PrepearFetchSequence($aIndexRange), $bIndexIsUid); + } + else + { + $this->oImapClient->MessageCopy($sToFolder, + \MailSo\Base\Utils::PrepearFetchSequence($aIndexRange), $bIndexIsUid); + + $this->MessageDelete($sFromFolder, $aIndexRange, $bIndexIsUid, true, $bExpungeAll); + } + + return $this; + } + + /** + * @param string $sFromFolder + * @param string $sToFolder + * @param array $aIndexRange + * @param bool $bIndexIsUid + * + * @return \MailSo\Mail\MailClient + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function MessageCopy($sFromFolder, $sToFolder, $aIndexRange, $bIndexIsUid) + { + if (0 === \strlen($sFromFolder) || 0 === \strlen($sToFolder) || + !\is_array($aIndexRange) || 0 === \count($aIndexRange)) + { + throw new \MailSo\Base\Exceptions\InvalidArgumentException(); + } + + $this->oImapClient->FolderSelect($sFromFolder); + $this->oImapClient->MessageCopy($sToFolder, + \MailSo\Base\Utils::PrepearFetchSequence($aIndexRange), $bIndexIsUid); + + return $this; + } + + /** + * @return \MailSo\Mail\MailClient + * + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function FolderUnSelect() + { + if ($this->oImapClient->IsSelected()) + { + $this->oImapClient->FolderUnSelect(); + } + + return $this; + } + + /** + * @param resource $rMessageStream + * @param int $iMessageStreamSize + * @param string $sFolderToSave + * @param array $aAppendFlags = null + * @param int $iUid = null + * + * @return \MailSo\Mail\MailClient + */ + public function MessageAppendStream($rMessageStream, $iMessageStreamSize, $sFolderToSave, $aAppendFlags = null, &$iUid = null) + { + if (!\is_resource($rMessageStream) || 0 === \strlen($sFolderToSave)) + { + throw new \MailSo\Base\Exceptions\InvalidArgumentException(); + } + + $this->oImapClient->MessageAppendStream( + $sFolderToSave, $rMessageStream, $iMessageStreamSize, $aAppendFlags, $iUid); + + return $this; + } + + /** + * @param string $sMessageFileName + * @param string $sFolderToSave + * @param array $aAppendFlags = null + * @param int &$iUid = null + * + * @return \MailSo\Mail\MailClient + */ + public function MessageAppendFile($sMessageFileName, $sFolderToSave, $aAppendFlags = null, &$iUid = null) + { + if (!@\is_file($sMessageFileName) || !@\is_readable($sMessageFileName)) + { + throw new \MailSo\Base\Exceptions\InvalidArgumentException(); + } + + $iMessageStreamSize = \filesize($sMessageFileName); + $rMessageStream = \fopen($sMessageFileName, 'rb'); + + $this->MessageAppendStream($rMessageStream, $iMessageStreamSize, $sFolderToSave, $aAppendFlags, $iUid); + + if (\is_resource($rMessageStream)) + { + @fclose($rMessageStream); + } + + return $this; + } + + /** + * @param string $sFolderName + * @param int $iCount + * @param int $iUnseenCount + * @param string $sUidNext + * @param string $sHighestModSeq + * + * @return void + */ + protected function initFolderValues($sFolderName, &$iCount, &$iUnseenCount, + &$sUidNext, &$sHighestModSeq = '') + { + $aTypes = array( + \MailSo\Imap\Enumerations\FolderResponseStatus::MESSAGES, + \MailSo\Imap\Enumerations\FolderResponseStatus::UNSEEN, + \MailSo\Imap\Enumerations\FolderResponseStatus::UIDNEXT + ); + + if ($this->oImapClient->IsSupported('CONDSTORE')) + { + $aTypes[] = \MailSo\Imap\Enumerations\FolderResponseStatus::HIGHESTMODSEQ; + } + + $aFolderStatus = $this->oImapClient->FolderStatus($sFolderName, $aTypes); + + $iCount = isset($aFolderStatus[\MailSo\Imap\Enumerations\FolderResponseStatus::MESSAGES]) + ? (int) $aFolderStatus[\MailSo\Imap\Enumerations\FolderResponseStatus::MESSAGES] : 0; + + $iUnseenCount = isset($aFolderStatus[\MailSo\Imap\Enumerations\FolderResponseStatus::UNSEEN]) + ? (int) $aFolderStatus[\MailSo\Imap\Enumerations\FolderResponseStatus::UNSEEN] : 0; + + $sUidNext = isset($aFolderStatus[\MailSo\Imap\Enumerations\FolderResponseStatus::UIDNEXT]) + ? (string) $aFolderStatus[\MailSo\Imap\Enumerations\FolderResponseStatus::UIDNEXT] : '0'; + + $sHighestModSeq = isset($aFolderStatus[\MailSo\Imap\Enumerations\FolderResponseStatus::HIGHESTMODSEQ]) + ? (string) $aFolderStatus[\MailSo\Imap\Enumerations\FolderResponseStatus::HIGHESTMODSEQ] : ''; + + if ($this->IsGmail() && + ('INBOX' === $sFolderName || '[gmail]' === \strtolower(\substr($sFolderName, 0, 7)))) + { + $oFolder = $this->oImapClient->FolderCurrentInformation(); + if ($oFolder && null !== $oFolder->Exists && $oFolder->FolderName === $sFolderName) + { + $iSubCount = (int) $oFolder->Exists; + if (0 < $iSubCount && $iSubCount < $iCount) + { + $iCount = $iSubCount; + } + } + } + } + + /** + * @return string + */ + public function GenerateImapClientHash() + { + return \md5('ImapClientHash/'. + $this->oImapClient->GetLogginedUser().'@'. + $this->oImapClient->GetConnectedHost().':'. + $this->oImapClient->GetConnectedPort() + ); + } + + /** + * @param string $sFolder + * @param int $iCount + * @param int $iUnseenCount + * @param string $sUidNext + * @param string $sHighestModSeq = '' + * + * @return string + */ + public function GenerateFolderHash($sFolder, $iCount, $iUnseenCount, $sUidNext, $sHighestModSeq = '') + { + $iUnseenCount = 0; // unneccessery + return \md5('FolderHash/'.$sFolder.'-'.$iCount.'-'.$iUnseenCount.'-'.$sUidNext.'-'. + $sHighestModSeq.'-'.$this->GenerateImapClientHash().'-'. + \MailSo\Config::$MessageListPermanentFilter + ); + } + + /** + * @param string $sFolderName + * @param string $sPrevUidNext + * @param string $sCurrentUidNext + * + * @return array + */ + private function getFolderNextMessageInformation($sFolderName, $sPrevUidNext, $sCurrentUidNext) + { + $aNewMessages = array(); + + if (0 < \strlen($sPrevUidNext) && (string) $sPrevUidNext !== (string) $sCurrentUidNext) + { + $this->oImapClient->FolderSelect($sFolderName); + + $aFetchResponse = $this->oImapClient->Fetch(array( + \MailSo\Imap\Enumerations\FetchType::INDEX, + \MailSo\Imap\Enumerations\FetchType::UID, + \MailSo\Imap\Enumerations\FetchType::FLAGS, + \MailSo\Imap\Enumerations\FetchType::BuildBodyCustomHeaderRequest(array( + \MailSo\Mime\Enumerations\Header::FROM_, + \MailSo\Mime\Enumerations\Header::SUBJECT, + \MailSo\Mime\Enumerations\Header::CONTENT_TYPE + )) + ), $sPrevUidNext.':*', true); + + if (\is_array($aFetchResponse) && 0 < \count($aFetchResponse)) + { + foreach ($aFetchResponse as /* @var $oFetchResponse \MailSo\Imap\FetchResponse */ $oFetchResponse) + { + $aFlags = \array_map('strtolower', $oFetchResponse->GetFetchValue( + \MailSo\Imap\Enumerations\FetchType::FLAGS)); + + if (!\in_array(\strtolower(\MailSo\Imap\Enumerations\MessageFlag::SEEN), $aFlags)) + { + $sUid = $oFetchResponse->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::UID); + $sHeaders = $oFetchResponse->GetHeaderFieldsValue(); + + $oHeaders = \MailSo\Mime\HeaderCollection::NewInstance()->Parse($sHeaders); + + $sContentTypeCharset = $oHeaders->ParameterValue( + \MailSo\Mime\Enumerations\Header::CONTENT_TYPE, + \MailSo\Mime\Enumerations\Parameter::CHARSET + ); + + $sCharset = ''; + if (0 < \strlen($sContentTypeCharset)) + { + $sCharset = $sContentTypeCharset; + } + + if (0 < \strlen($sCharset)) + { + $oHeaders->SetParentCharset($sCharset); + } + + $aNewMessages[] = array( + 'Folder' => $sFolderName, + 'Uid' => $sUid, + 'Subject' => $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::SUBJECT, 0 === \strlen($sCharset)), + 'From' => $oHeaders->GetAsEmailCollection(\MailSo\Mime\Enumerations\Header::FROM_, 0 === \strlen($sCharset)) + ); + } + } + } + } + + return $aNewMessages; + } + + /** + * @param string $sFolderName + * @param string $sPrevUidNext = '' + * @param array $aUids = '' + * + * @return string + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function FolderInformation($sFolderName, $sPrevUidNext = '', $aUids = array()) + { + $aFlags = array(); + + $bSelect = false; + if ($this->IsGmail() && + ('INBOX' === $sFolderName || '[gmail]' === \strtolower(\substr($sFolderName, 0, 7)))) + { + $this->oImapClient->FolderSelect($sFolderName); + $bSelect = true; + } + + if (\is_array($aUids) && 0 < \count($aUids)) + { + if (!$bSelect) + { + $this->oImapClient->FolderSelect($sFolderName); + } + + $aFetchResponse = $this->oImapClient->Fetch(array( + \MailSo\Imap\Enumerations\FetchType::INDEX, + \MailSo\Imap\Enumerations\FetchType::UID, + \MailSo\Imap\Enumerations\FetchType::FLAGS + ), \MailSo\Base\Utils::PrepearFetchSequence($aUids), true); + + if (\is_array($aFetchResponse) && 0 < \count($aFetchResponse)) + { + foreach ($aFetchResponse as $oFetchResponse) + { + $sUid = $oFetchResponse->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::UID); + $aFlags[(\is_numeric($sUid) ? (int) $sUid : 0)] = + $oFetchResponse->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::FLAGS); + } + } + } + + $iCount = 0; + $iUnseenCount = 0; + $sUidNext = '0'; + $sHighestModSeq = ''; + + $this->initFolderValues($sFolderName, $iCount, $iUnseenCount, $sUidNext, $sHighestModSeq); + + $aResult = array( + 'Folder' => $sFolderName, + 'Hash' => $this->GenerateFolderHash($sFolderName, $iCount, $iUnseenCount, $sUidNext, $sHighestModSeq), + 'MessageCount' => $iCount, + 'MessageUnseenCount' => $iUnseenCount, + 'UidNext' => $sUidNext, + 'Flags' => $aFlags, + 'HighestModSeq' => $sHighestModSeq, + 'NewMessages' => 'INBOX' === $sFolderName && \MailSo\Config::$CheckNewMessages ? + $this->getFolderNextMessageInformation($sFolderName, $sPrevUidNext, $sUidNext) : array() + ); + + return $aResult; + } + + /** + * @param string $sFolderName + * + * @return string + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function FolderHash($sFolderName) + { + $iCount = 0; + $iUnseenCount = 0; + $sUidNext = '0'; + $sHighestModSeq = ''; + + $this->initFolderValues($sFolderName, $iCount, $iUnseenCount, $sUidNext, $sHighestModSeq); + + return $this->GenerateFolderHash($sFolderName, $iCount, $iUnseenCount, $sUidNext, $sHighestModSeq); + } + + /** + * @return int + * + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function InboxUnreadCount() + { + $aFolderStatus = $this->oImapClient->FolderStatus('INBOX', array( + \MailSo\Imap\Enumerations\FolderResponseStatus::UNSEEN + )); + + $iResult = isset($aFolderStatus[\MailSo\Imap\Enumerations\FolderResponseStatus::UNSEEN]) ? + (int) $aFolderStatus[\MailSo\Imap\Enumerations\FolderResponseStatus::UNSEEN] : 0; + + return 0 < $iResult ? $iResult : 0; + } + + /** + * @return bool + */ + public function IsGmail() + { + return 'ssl://imap.gmail.com' === \strtolower($this->oImapClient->GetConnectedHost()); + } + + /** + * @param string $sSearch + * @param bool $bDetectGmail = true + * + * @return string + */ + private function escapeSearchString($sSearch, $bDetectGmail = true) + { + return !\MailSo\Base\Utils::IsAscii($sSearch) + ? '{'.\strlen($sSearch).'}'."\r\n".$sSearch : $this->oImapClient->EscapeString($sSearch); +// return ($bDetectGmail && !\MailSo\Base\Utils::IsAscii($sSearch) && $this->IsGmail()) +// ? '{'.\strlen($sSearch).'+}'."\r\n".$sSearch : $this->oImapClient->EscapeString($sSearch); + } + + /** + * @param string $sDate + * @param int $iTimeZoneOffset + * + * @return int + */ + private function parseSearchDate($sDate, $iTimeZoneOffset) + { + $iResult = 0; + if (0 < \strlen($sDate)) + { + $oDateTime = \DateTime::createFromFormat('Y.m.d', $sDate, \MailSo\Base\DateTimeHelper::GetUtcTimeZoneObject()); + return $oDateTime ? $oDateTime->getTimestamp() - $iTimeZoneOffset : 0; + } + + return $iResult; + } + + /** + * @param string $sSize + * + * @return int + */ + private function parseFriendlySize($sSize) + { + $sSize = preg_replace('/[^0-9bBkKmM]/', '', $sSize); + + $iResult = 0; + $aMatch = array(); + + if (\preg_match('/([\d]+)(B|KB|M|MB|G|GB)$/i', $sSize, $aMatch) && isset($aMatch[1], $aMatch[2])) + { + $iResult = (int) $aMatch[1]; + switch (\strtoupper($aMatch[2])) + { + case 'K': + case 'KB': + $iResult *= 1024; + case 'M': + case 'MB': + $iResult *= 1024; + case 'G': + case 'GB': + $iResult *= 1024; + } + } + else + { + $iResult = (int) $sSize; + } + + return $iResult; + } + + /** + * @param string $sSearch + * + * @return array + */ + private function parseSearchString($sSearch) + { + $aResult = array( + 'OTHER' => '' + ); + + $aCache = array(); + + $sReg = 'e?mail|from|to|subject|has|is|date|text|body|size|larger|bigger|smaller|maxsize|minsize'; + + $sSearch = \MailSo\Base\Utils::StripSpaces($sSearch); + $sSearch = \trim(\preg_replace('/('.$sReg.'): /i', '\\1:', $sSearch)); + + $mMatch = array(); + \preg_match_all('/".*?(? $sName) + { + if (isset($mMatch[2][$iIndex]) && 0 < \strlen($mMatch[2][$iIndex])) + { + $sName = \strtoupper($sName); + $sValue = $mMatch[2][$iIndex]; + switch ($sName) + { + case 'TEXT': + case 'BODY': + case 'EMAIL': + case 'MAIL': + case 'FROM': + case 'TO': + case 'SUBJECT': + case 'IS': + case 'HAS': + case 'SIZE': + case 'SMALLER': + case 'LARGER': + case 'BIGGER': + case 'MAXSIZE': + case 'MINSIZE': + case 'DATE': + if ('MAIL' === $sName) + { + $sName = 'EMAIL'; + } + if ('BODY' === $sName) + { + $sName = 'TEXT'; + } + if ('SIZE' === $sName || 'BIGGER' === $sName || 'MINSIZE' === $sName) + { + $sName = 'LARGER'; + } + if ('MAXSIZE' === $sName) + { + $sName = 'SMALLER'; + } + $aResult[$sName] = $sValue; + break; + } + } + } + } + + $aResult['OTHER'] = $sSearch; + foreach ($aResult as $sName => $sValue) + { + if (isset($aCache[$sValue])) + { + $aResult[$sName] = \trim($aCache[$sValue], '"\' '); + } + } + + return $aResult; + } + + /** + * @param string $sSearch + * @param string $sFilter + * @param int $iTimeZoneOffset = 0 + * @param bool $bUseCache = true + * + * @return string + */ + private function getImapSearchCriterias($sSearch, $sFilter, $iTimeZoneOffset = 0, &$bUseCache = true) + { + $bUseCache = true; + $iTimeFilter = 0; + $aCriteriasResult = array(); + + if (0 < \MailSo\Config::$MessageListDateFilter) + { + $iD = \time() - 3600 * 24 * 30 * \MailSo\Config::$MessageListDateFilter; + $iTimeFilter = \gmmktime(1, 1, 1, \gmdate('n', $iD), 1, \gmdate('Y', $iD)); + } + + if (0 < \strlen(\trim($sSearch))) + { + $sGmailRawSearch = ''; + $sResultBodyTextSearch = ''; + + $aLines = $this->parseSearchString($sSearch); + $bIsGmail = $this->oImapClient->IsSupported('X-GM-EXT-1'); + + if (1 === \count($aLines) && isset($aLines['OTHER'])) + { + $sValue = $this->escapeSearchString($aLines['OTHER']); + + if (\MailSo\Config::$MessageListFastSimpleSearch) + { + $aCriteriasResult[] = 'OR OR OR'; + $aCriteriasResult[] = 'FROM'; + $aCriteriasResult[] = $sValue; + $aCriteriasResult[] = 'TO'; + $aCriteriasResult[] = $sValue; + $aCriteriasResult[] = 'CC'; + $aCriteriasResult[] = $sValue; + $aCriteriasResult[] = 'SUBJECT'; + $aCriteriasResult[] = $sValue; + } + else + { + $aCriteriasResult[] = 'TEXT'; + $aCriteriasResult[] = $sValue; + } + } + else + { + if (isset($aLines['EMAIL'])) + { + $sValue = $this->escapeSearchString($aLines['EMAIL']); + + $aCriteriasResult[] = 'OR OR'; + $aCriteriasResult[] = 'FROM'; + $aCriteriasResult[] = $sValue; + $aCriteriasResult[] = 'TO'; + $aCriteriasResult[] = $sValue; + $aCriteriasResult[] = 'CC'; + $aCriteriasResult[] = $sValue; + + unset($aLines['EMAIL']); + } + + if (isset($aLines['TO'])) + { + $sValue = $this->escapeSearchString($aLines['TO']); + + $aCriteriasResult[] = 'OR'; + $aCriteriasResult[] = 'TO'; + $aCriteriasResult[] = $sValue; + $aCriteriasResult[] = 'CC'; + $aCriteriasResult[] = $sValue; + + unset($aLines['TO']); + } + + $sMainText = ''; + foreach ($aLines as $sName => $sRawValue) + { + if ('' === \trim($sRawValue)) + { + continue; + } + + $sValue = $this->escapeSearchString($sRawValue); + switch ($sName) + { + case 'FROM': + $aCriteriasResult[] = 'FROM'; + $aCriteriasResult[] = $sValue; + break; + case 'SUBJECT': + $aCriteriasResult[] = 'SUBJECT'; + $aCriteriasResult[] = $sValue; + break; + case 'OTHER': + case 'TEXT': + $sMainText .= ' '.$sRawValue; + break; + case 'HAS': + $aValue = \explode(',', \strtolower($sRawValue)); + $aValue = \array_map('trim', $aValue); + + $aCompareArray = array('file', 'files', 'attach', 'attachs', 'attachment', 'attachments'); + if (\count($aCompareArray) > \count(\array_diff($aCompareArray, $aValue))) + { + if ($bIsGmail) + { + $sGmailRawSearch .= ' has:attachment'; + } + else + { + // Simple, is not detailed search (Sometimes doesn't work) + $aCriteriasResult[] = 'OR OR OR'; + $aCriteriasResult[] = 'HEADER Content-Type application/'; + $aCriteriasResult[] = 'HEADER Content-Type multipart/m'; + $aCriteriasResult[] = 'HEADER Content-Type multipart/signed'; + $aCriteriasResult[] = 'HEADER Content-Type multipart/report'; + } + } + + case 'IS': + $aValue = \explode(',', \strtolower($sRawValue)); + $aValue = \array_map('trim', $aValue); + + $aCompareArray = array('flag', 'flagged', 'star', 'starred', 'pinned'); + $aCompareArray2 = array('unflag', 'unflagged', 'unstar', 'unstarred', 'unpinned'); + if (\count($aCompareArray) > \count(\array_diff($aCompareArray, $aValue))) + { + $aCriteriasResult[] = 'FLAGGED'; + $bUseCache = false; + } + else if (\count($aCompareArray2) > \count(\array_diff($aCompareArray2, $aValue))) + { + $aCriteriasResult[] = 'UNFLAGGED'; + $bUseCache = false; + } + + $aCompareArray = array('unread', 'unseen'); + $aCompareArray2 = array('read', 'seen'); + if (\count($aCompareArray) > \count(\array_diff($aCompareArray, $aValue))) + { + $aCriteriasResult[] = 'UNSEEN'; + $bUseCache = false; + } + else if (\count($aCompareArray2) > \count(\array_diff($aCompareArray2, $aValue))) + { + $aCriteriasResult[] = 'SEEN'; + $bUseCache = false; + } + break; + + case 'LARGER': + $aCriteriasResult[] = 'LARGER'; + $aCriteriasResult[] = $this->parseFriendlySize($sRawValue); + break; + case 'SMALLER': + $aCriteriasResult[] = 'SMALLER'; + $aCriteriasResult[] = $this->parseFriendlySize($sRawValue); + break; + case 'DATE': + $iDateStampFrom = $iDateStampTo = 0; + + $sDate = $sRawValue; + $aDate = \explode('/', $sDate); + + if (\is_array($aDate) && 2 === \count($aDate)) + { + if (0 < \strlen($aDate[0])) + { + $iDateStampFrom = $this->parseSearchDate($aDate[0], $iTimeZoneOffset); + } + + if (0 < \strlen($aDate[1])) + { + $iDateStampTo = $this->parseSearchDate($aDate[1], $iTimeZoneOffset); + $iDateStampTo += 60 * 60 * 24; + } + } + else + { + if (0 < \strlen($sDate)) + { + $iDateStampFrom = $this->parseSearchDate($sDate, $iTimeZoneOffset); + $iDateStampTo = $iDateStampFrom + 60 * 60 * 24; + } + } + + if (0 < $iDateStampFrom) + { + $aCriteriasResult[] = 'SINCE'; + $aCriteriasResult[] = \gmdate('j-M-Y', $iTimeFilter > $iDateStampFrom ? + $iTimeFilter : $iDateStampFrom); + + $iTimeFilter = 0; + } + + if (0 < $iDateStampTo) + { + $aCriteriasResult[] = 'BEFORE'; + $aCriteriasResult[] = \gmdate('j-M-Y', $iDateStampTo); + } + break; + } + } + + if ('' !== \trim($sMainText)) + { + $sMainText = \trim(\MailSo\Base\Utils::StripSpaces($sMainText), '"'); + if ($bIsGmail) + { + $sGmailRawSearch .= ' '.$sMainText; + } + else + { + $sResultBodyTextSearch .= ' '.$sMainText; + } + } + } + + $sGmailRawSearch = \trim($sGmailRawSearch); + if ($bIsGmail && 0 < \strlen($sGmailRawSearch)) + { + $aCriteriasResult[] = 'X-GM-RAW'; + $aCriteriasResult[] = $this->escapeSearchString($sGmailRawSearch, false); + } + + $sResultBodyTextSearch = \trim($sResultBodyTextSearch); + if (0 < \strlen($sResultBodyTextSearch)) + { + $aCriteriasResult[] = 'BODY'; + $aCriteriasResult[] = $this->escapeSearchString($sResultBodyTextSearch); + } + } + + $sCriteriasResult = \trim(\implode(' ', $aCriteriasResult)); + + if (0 < $iTimeFilter) + { + $sCriteriasResult .= ' SINCE '.\gmdate('j-M-Y', $iTimeFilter); + } + + $sCriteriasResult = \trim($sCriteriasResult); + if (\MailSo\Config::$MessageListUndeletedOnly) + { + $sCriteriasResult = \trim($sCriteriasResult.' UNDELETED'); + } + + $sFilter = \trim($sFilter); + if ('' !== $sFilter) + { + $sCriteriasResult .= ' '.$sFilter; + } + + $sCriteriasResult = \trim($sCriteriasResult); + if ('' !== \MailSo\Config::$MessageListPermanentFilter) + { + $sCriteriasResult = \trim($sCriteriasResult.' '.\MailSo\Config::$MessageListPermanentFilter); + } + + $sCriteriasResult = \trim($sCriteriasResult); + if ('' === $sCriteriasResult) + { + $sCriteriasResult = 'ALL'; + } + + return $sCriteriasResult; + } + + /** + * @param array $aThreads + * @return array + */ + private function threadArrayMap($aThreads) + { + $aNew = array(); + foreach ($aThreads as $mItem) + { + if (!\is_array($mItem)) + { + $aNew[] = $mItem; + } + else + { + $mMap = $this->threadArrayMap($mItem); + if (\is_array($mMap) && 0 < \count($mMap)) + { + $aNew = \array_merge($aNew, $mMap); + } + } + } + + return $aNew; + } + + /** + * @param array $aThreads + * + * @return array + */ + private function compileThreadArray($aThreads) + { + $aResult = array(); + foreach ($aThreads as $mItem) + { + if (\is_array($mItem)) + { + $aMap = $this->threadArrayMap($mItem); + if (\is_array($aMap)) + { + if (1 < \count($aMap)) + { + $aResult[] = $aMap; + } + else if (0 < \count($aMap)) + { + $aResult[] = $aMap[0]; + } + } + } + else + { + $aResult[] = $mItem; + } + } + + return $aResult; + } + + /** + * @param string $sFolderName + * @param string $sFolderHash + * @param array $aIndexOrUids + * @param \MailSo\Cache\CacheClient $oCacher + * @param bool $bCacheOnly = false + * + * @return array + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function MessageListThreadsMap($sFolderName, $sFolderHash, $aIndexOrUids, $oCacher, $bCacheOnly = false) + { + $iThreadLimit = \MailSo\Config::$LargeThreadLimit; + + $sSearchHash = ''; + if (0 < \MailSo\Config::$MessageListDateFilter) + { + $iD = \time() - 3600 * 24 * 30 * \MailSo\Config::$MessageListDateFilter; + $iTimeFilter = \gmmktime(1, 1, 1, \gmdate('n', $iD), 1, \gmdate('Y', $iD)); + + $sSearchHash .= ' SINCE '.\gmdate('j-M-Y', $iTimeFilter); + } + + if ('' === \trim($sSearchHash)) + { + $sSearchHash = 'ALL'; + } + + if ($oCacher && $oCacher->IsInited()) + { + $sSerializedHashKey = + 'ThreadsMapSorted/'.$sSearchHash.'/'. + 'Limit='.$iThreadLimit.'/'.$sFolderName.'/'.$sFolderHash; + + if ($this->oLogger) + { + $this->oLogger->Write($sSerializedHashKey); + } + + $sSerializedUids = $oCacher->Get($sSerializedHashKey); + if (!empty($sSerializedUids)) + { + $aSerializedUids = @\json_decode($sSerializedUids, true); + if (isset($aSerializedUids['ThreadsUids']) && \is_array($aSerializedUids['ThreadsUids'])) + { + if ($this->oLogger) + { + $this->oLogger->Write('Get Serialized Thread UIDS from cache ("'.$sFolderName.'" / '.$sSearchHash.') [count:'.\count($aSerializedUids['ThreadsUids']).']'); + } + + return $aSerializedUids['ThreadsUids']; + } + } + } + + if ($bCacheOnly) + { + return null; + } + + $this->oImapClient->FolderExamine($sFolderName); + + $aThreadUids = array(); + try + { + $aThreadUids = $this->oImapClient->MessageSimpleThread($sSearchHash); + } + catch (\MailSo\Imap\Exceptions\RuntimeException $oException) + { + unset($oException); + $aThreadUids = array(); + } + + $aResult = array(); + $aCompiledThreads = $this->compileThreadArray($aThreadUids); + + foreach ($aCompiledThreads as $mData) + { + if (\is_array($mData)) + { + foreach ($mData as $mSubData) + { + $aResult[(int) $mSubData] = + \array_diff($mData, array((int) $mSubData)); + } + } + else if (\is_int($mData) || \is_string($mData)) + { + $aResult[(int) $mData] = (int) $mData; + } + } + + $aParentsMap = array(); + foreach ($aIndexOrUids as $iUid) + { + if (isset($aResult[$iUid]) && \is_array($aResult[$iUid])) + { + foreach ($aResult[$iUid] as $iTempUid) + { + $aParentsMap[$iTempUid] = $iUid; + if (isset($aResult[$iTempUid])) + { + unset($aResult[$iTempUid]); + } + } + } + } + + $aSortedThreads = array(); + foreach ($aIndexOrUids as $iUid) + { + if (isset($aResult[$iUid])) + { + $aSortedThreads[$iUid] = $iUid; + } + } + + foreach ($aIndexOrUids as $iUid) + { + if (!isset($aSortedThreads[$iUid]) && + isset($aParentsMap[$iUid]) && + isset($aSortedThreads[$aParentsMap[$iUid]])) + { + if (!\is_array($aSortedThreads[$aParentsMap[$iUid]])) + { + $aSortedThreads[$aParentsMap[$iUid]] = array(); + } + + $aSortedThreads[$aParentsMap[$iUid]][] = $iUid; + } + } + + $aResult = $aSortedThreads; + unset($aParentsMap, $aSortedThreads); + + $aTemp = array(); + foreach ($aResult as $iUid => $mValue) + { + if (0 < $iThreadLimit && \is_array($mValue) && $iThreadLimit < \count($mValue)) + { + $aParts = \array_chunk($mValue, $iThreadLimit); + if (0 < count($aParts)) + { + foreach ($aParts as $iIndex => $aItem) + { + if (0 === $iIndex) + { + $aResult[$iUid] = $aItem; + } + else if (0 < $iIndex && \is_array($aItem)) + { + $mFirst = \array_shift($aItem); + if (!empty($mFirst)) + { + $aTemp[$mFirst] = 0 < \count($aItem) ? $aItem : $mFirst; + } + } + } + } + } + } + + foreach ($aTemp as $iUid => $mValue) + { + $aResult[$iUid] = $mValue; + } + + unset($aTemp); + + $aLastResult = array(); + foreach ($aIndexOrUids as $iUid) + { + if (isset($aResult[$iUid])) + { + $aLastResult[$iUid] = $aResult[$iUid]; + } + } + + $aResult = $aLastResult; + unset($aLastResult); + + if ($oCacher && $oCacher->IsInited() && !empty($sSerializedHashKey)) + { + $oCacher->Set($sSerializedHashKey, @\json_encode(array( + 'ThreadsUids' => $aResult + ))); + + if ($this->oLogger) + { + $this->oLogger->Write('Save Serialized Thread UIDS to cache ("'.$sFolderName.'" / '.$sSearchHash.') [count:'.\count($aResult).']'); + } + } + + return $aResult; + } + + /** + * @param \MailSo\Mail\MessageCollection &$oMessageCollection + * @param array $aRequestIndexOrUids + * @param bool $bIndexAsUid + * @param bool $bSimple = false + * + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function MessageListByRequestIndexOrUids(&$oMessageCollection, $aRequestIndexOrUids, $bIndexAsUid, $bSimple = false) + { + if (\is_array($aRequestIndexOrUids) && 0 < \count($aRequestIndexOrUids)) + { + $aFetchResponse = $this->oImapClient->Fetch(array( + \MailSo\Imap\Enumerations\FetchType::INDEX, + \MailSo\Imap\Enumerations\FetchType::UID, + \MailSo\Imap\Enumerations\FetchType::RFC822_SIZE, + \MailSo\Imap\Enumerations\FetchType::INTERNALDATE, + \MailSo\Imap\Enumerations\FetchType::FLAGS, + \MailSo\Imap\Enumerations\FetchType::BODYSTRUCTURE, + $bSimple ? + $this->getEnvelopeOrHeadersRequestStringForSimpleList() : + $this->getEnvelopeOrHeadersRequestString() + ), \MailSo\Base\Utils::PrepearFetchSequence($aRequestIndexOrUids), $bIndexAsUid); + + if (\is_array($aFetchResponse) && 0 < \count($aFetchResponse)) + { + $aFetchIndexArray = array(); + $oFetchResponseItem = null; + foreach ($aFetchResponse as /* @var $oFetchResponseItem \MailSo\Imap\FetchResponse */ &$oFetchResponseItem) + { + $aFetchIndexArray[($bIndexAsUid) + ? $oFetchResponseItem->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::UID) + : $oFetchResponseItem->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::INDEX)] =& $oFetchResponseItem; + + unset($oFetchResponseItem); + } + + foreach ($aRequestIndexOrUids as $iFUid) + { + if (isset($aFetchIndexArray[$iFUid])) + { + $oMessageCollection->Add( + Message::NewFetchResponseInstance( + $oMessageCollection->FolderName, $aFetchIndexArray[$iFUid])); + } + } + } + } + } + + /** + * @return bool + * + * @throws \MailSo\Net\Exceptions\Exception + */ + public function IsThreadsSupported() + { + return $this->oImapClient->IsSupported('THREAD=REFS') || + $this->oImapClient->IsSupported('THREAD=REFERENCES') || + $this->oImapClient->IsSupported('THREAD=ORDEREDSUBJECT'); + } + + /** + * @param string $sFolderName + * @param array $aUids + * + * @return \MailSo\Mail\MessageCollection + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function MessageListSimple($sFolderName, $aUids) + { + if (0 === \strlen($sFolderName) || !\MailSo\Base\Validator::NotEmptyArray($aUids)) + { + throw new \MailSo\Base\Exceptions\InvalidArgumentException(); + } + + $this->oImapClient->FolderExamine($sFolderName); + + $oMessageCollection = \MailSo\Mail\MessageCollection::NewInstance(); + $oMessageCollection->FolderName = $sFolderName; + + $this->MessageListByRequestIndexOrUids($oMessageCollection, $aUids, true, true); + + return $oMessageCollection->GetAsArray(); + } + + /** + * @param \MailSo\Cache\CacheClient|null $oCacher + * @param string $sSearch + * @param string $sFilter + * @param string $sFolderName + * @param string $sFolderHash + * @param bool $bUseSortIfSupported = false + * + * @return array + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function GetUids($oCacher, $sSearch, $sFilter, $sFolderName, $sFolderHash, $bUseSortIfSupported = false) + { + $aResultUids = false; + $bUidsFromCacher = false; + $bUseCacheAfterSearch = true; + + $sSerializedHash = ''; + $sSerializedLog = ''; + + $bUseSortIfSupported = $bUseSortIfSupported ? !!$this->oImapClient->IsSupported('SORT') : false; + + if (0 < \strlen($sSearch)) + { + $bUseSortIfSupported = false; + } + + $sSearchCriterias = $this->getImapSearchCriterias($sSearch, $sFilter, 0, $bUseCacheAfterSearch); + if ($bUseCacheAfterSearch && $oCacher && $oCacher->IsInited()) + { + $sSerializedHash = 'GetUids/'. + ($bUseSortIfSupported ? 'S': 'N').'/'. + $this->GenerateImapClientHash().'/'. + $sFolderName.'/'.$sSearchCriterias; + + $sSerializedLog = '"'.$sFolderName.'" / '.$sSearchCriterias.''; + + $sSerialized = $oCacher->Get($sSerializedHash); + if (!empty($sSerialized)) + { + $aSerialized = @\json_decode($sSerialized, true); + if (\is_array($aSerialized) && isset($aSerialized['FolderHash'], $aSerialized['Uids']) && + $sFolderHash === $aSerialized['FolderHash'] && + \is_array($aSerialized['Uids']) + ) + { + if ($this->oLogger) + { + $this->oLogger->Write('Get Serialized UIDS from cache ('.$sSerializedLog.') [count:'.\count($aSerialized['Uids']).']'); + } + + $aResultUids = $aSerialized['Uids']; + $bUidsFromCacher = true; + } + } + } + + if (!\is_array($aResultUids)) + { + $aResultUids = $bUseSortIfSupported ? + $this->oImapClient->MessageSimpleSort(array('REVERSE ARRIVAL'), $sSearchCriterias, true) : + $this->oImapClient->MessageSimpleSearch($sSearchCriterias, true, \MailSo\Base\Utils::IsAscii($sSearchCriterias) ? '' : 'UTF-8') + ; + + if (!$bUidsFromCacher && $bUseCacheAfterSearch && \is_array($aResultUids) && $oCacher && $oCacher->IsInited() && 0 < \strlen($sSerializedHash)) + { + $oCacher->Set($sSerializedHash, @\json_encode(array( + 'FolderHash' => $sFolderHash, + 'Uids' => $aResultUids + ))); + + if ($this->oLogger) + { + $this->oLogger->Write('Save Serialized UIDS to cache ('.$sSerializedLog.') [count:'.\count($aResultUids).']'); + } + } + } + + return \is_array($aResultUids) ? $aResultUids : array(); + } + + /** + * @param string $sFolderName + * @param int $iOffset = 0 + * @param int $iLimit = 10 + * @param string $sSearch = '' + * @param string $sPrevUidNext = '' + * @param \MailSo\Cache\CacheClient|null $oCacher = null + * @param bool $bUseSortIfSupported = false + * @param bool $bUseThreadSortIfSupported = false + * @param bool $bUseESearchOrESortRequest = false + * @param string $sThreadUid = '' + * @param string $sFilter = '' + * + * @return \MailSo\Mail\MessageCollection + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function MessageList($sFolderName, $iOffset = 0, $iLimit = 10, $sSearch = '', $sPrevUidNext = '', $oCacher = null, + $bUseSortIfSupported = false, $bUseThreadSortIfSupported = false, $sThreadUid = '', $sFilter = '') + { + $sFilter = \trim($sFilter); + $sSearch = \trim($sSearch); + if (!\MailSo\Base\Validator::RangeInt($iOffset, 0) || + !\MailSo\Base\Validator::RangeInt($iLimit, 0, 999)) + { + throw new \MailSo\Base\Exceptions\InvalidArgumentException(); + } + + $bUseFilter = '' !== $sFilter; + + $this->oImapClient->FolderSelect($sFolderName); + + $oMessageCollection = MessageCollection::NewInstance(); + $oMessageCollection->FolderName = $sFolderName; + $oMessageCollection->Offset = $iOffset; + $oMessageCollection->Limit = $iLimit; + $oMessageCollection->Search = $sSearch; + $oMessageCollection->ThreadUid = $sThreadUid; + $oMessageCollection->Filtered = '' !== \MailSo\Config::$MessageListPermanentFilter; + + $aUids = array(); + $mAllSortedUids = null; + $mAllThreads = null; + + $iThreadUid = empty($sThreadUid) ? 0 : (int) $sThreadUid; + + $iMessageRealCount = 0; + $iMessageUnseenCount = 0; + $sUidNext = '0'; + $sHighestModSeq = ''; + + $bUseSortIfSupported = $bUseSortIfSupported ? $this->oImapClient->IsSupported('SORT') : false; + + $bUseThreadSortIfSupported = $bUseThreadSortIfSupported ? + ($this->oImapClient->IsSupported('THREAD=REFS') || $this->oImapClient->IsSupported('THREAD=REFERENCES') || $this->oImapClient->IsSupported('THREAD=ORDEREDSUBJECT')) : false; + + if (!empty($sThreadUid) && !$bUseThreadSortIfSupported) + { + throw new \MailSo\Base\Exceptions\InvalidArgumentException(); + } + + if (!$oCacher || !($oCacher instanceof \MailSo\Cache\CacheClient)) + { + $oCacher = null; + } + + $this->initFolderValues($sFolderName, $iMessageRealCount, $iMessageUnseenCount, $sUidNext, $sHighestModSeq); + + if ($bUseFilter) + { + $iMessageUnseenCount = 0; + } + + $oMessageCollection->FolderHash = $this->GenerateFolderHash( + $sFolderName, $iMessageRealCount, $iMessageUnseenCount, $sUidNext, $sHighestModSeq); + + $oMessageCollection->UidNext = $sUidNext; + + if (empty($sThreadUid) && 0 < \strlen($sPrevUidNext) && 'INBOX' === $sFolderName) + { + $oMessageCollection->NewMessages = $this->getFolderNextMessageInformation( + $sFolderName, $sPrevUidNext, $sUidNext); + } + + $bSearch = false; + $bMessageListOptimization = 0 < \MailSo\Config::$MessageListCountLimitTrigger && + \MailSo\Config::$MessageListCountLimitTrigger < $iMessageRealCount; + + if ($bMessageListOptimization) + { + $bUseSortIfSupported = false; + $bUseThreadSortIfSupported = false; + } + + if (0 < $iMessageRealCount && !$bMessageListOptimization) + { + $mAllSortedUids = $this->GetUids($oCacher, '', $sFilter, + $oMessageCollection->FolderName, $oMessageCollection->FolderHash, $bUseSortIfSupported); + + $mAllThreads = $bUseThreadSortIfSupported ? $this->MessageListThreadsMap( + $oMessageCollection->FolderName, $oMessageCollection->FolderHash, $mAllSortedUids, $oCacher) : null; + + if ($bUseThreadSortIfSupported && 0 < $iThreadUid && \is_array($mAllThreads)) + { + $aUids = array(); + $iResultRootUid = 0; + + if (isset($mAllThreads[$iThreadUid])) + { + $iResultRootUid = $iThreadUid; + if (\is_array($mAllThreads[$iThreadUid])) + { + $aUids = $mAllThreads[$iThreadUid]; + } + } + else + { + foreach ($mAllThreads as $iRootUid => $mSubUids) + { + if (\is_array($mSubUids) && \in_array($iThreadUid, $mSubUids)) + { + $iResultRootUid = $iRootUid; + $aUids = $mSubUids; + continue; + } + } + } + + if (0 < $iResultRootUid && \in_array($iResultRootUid, $mAllSortedUids)) + { + \array_unshift($aUids, $iResultRootUid); + } + } + else if ($bUseThreadSortIfSupported && \is_array($mAllThreads)) + { + $aUids = \array_keys($mAllThreads); + } + else + { + $bUseThreadSortIfSupported = false; + $aUids = $mAllSortedUids; + } + + if (0 < \strlen($sSearch) && \is_array($aUids)) + { + $aSearchedUids = $this->GetUids($oCacher, $sSearch, $sFilter, + $oMessageCollection->FolderName, $oMessageCollection->FolderHash); + + if (\is_array($aSearchedUids) && 0 < \count($aSearchedUids)) + { + $aFlippedSearchedUids = \array_flip($aSearchedUids); + + $bSearch = true; + $aNewUids = array(); + + foreach ($aUids as $iUid) + { + if (isset($aFlippedSearchedUids[$iUid])) + { + $aNewUids[] = $iUid; + } + else if ($bUseThreadSortIfSupported && 0 === $iThreadUid && isset($mAllThreads[$iUid]) && \is_array($mAllThreads[$iUid])) + { + foreach ($mAllThreads[$iUid] as $iSubUid) + { + if (isset($aFlippedSearchedUids[$iSubUid])) + { + $aNewUids[] = $iUid; + continue; + } + } + } + } + + $aUids = \array_unique($aNewUids); + unset($aNewUids); + } + else + { + $aUids = array(); + } + } + + if (\is_array($aUids)) + { + $oMessageCollection->MessageCount = $iMessageRealCount; + $oMessageCollection->MessageUnseenCount = $iMessageUnseenCount; + $oMessageCollection->MessageResultCount = \count($aUids); + + if (0 < \count($aUids)) + { + $aRequestUids = \array_slice($aUids, $iOffset, $iLimit); + $this->MessageListByRequestIndexOrUids($oMessageCollection, $aRequestUids, true); + } + } + } + else if (0 < $iMessageRealCount) + { + if ($this->oLogger) + { + $this->oLogger->Write('List optimization (count: '.$iMessageRealCount. + ', limit:'.\MailSo\Config::$MessageListCountLimitTrigger.')'); + } + + $oMessageCollection->MessageCount = $iMessageRealCount; + $oMessageCollection->MessageUnseenCount = $iMessageUnseenCount; + + if (0 < \strlen($sSearch) || $bUseFilter) + { + $aUids = $this->GetUids($oCacher, $sSearch, $sFilter, + $oMessageCollection->FolderName, $oMessageCollection->FolderHash); + + if (0 < \count($aUids)) + { + $oMessageCollection->MessageResultCount = \count($aUids); + + $aRequestUids = \array_slice($aUids, $iOffset, $iLimit); + $this->MessageListByRequestIndexOrUids($oMessageCollection, $aRequestUids, true); + } + else + { + $oMessageCollection->MessageResultCount = 0; + } + } + else + { + $oMessageCollection->MessageResultCount = $iMessageRealCount; + + if (1 < $iMessageRealCount) + { + $aRequestIndexes = \array_slice(array_reverse(range(1, $iMessageRealCount)), $iOffset, $iLimit); + } + else + { + $aRequestIndexes = \array_slice(array(1), $iOffset, $iLimit); + } + + $this->MessageListByRequestIndexOrUids($oMessageCollection, $aRequestIndexes, false); + } + } + + if ($bUseThreadSortIfSupported && 0 === $iThreadUid && \is_array($mAllThreads) && 0 < \count($mAllThreads)) + { + $oMessageCollection->ForeachList(function (/* @var $oMessage \MailSo\Mail\Message */ $oMessage) use ($mAllThreads) { + + $iUid = $oMessage->Uid(); + if (isset($mAllThreads[$iUid]) && \is_array($mAllThreads[$iUid]) && 0 < \count($mAllThreads[$iUid])) + { + $aSubThreads = $mAllThreads[$iUid]; + \array_unshift($aSubThreads, $iUid); + + $oMessage->SetThreads(\array_map('trim', $aSubThreads)); + unset($aSubThreads); + } + }); + } + + return $oMessageCollection; + } + + /** + * @return array|false + */ + public function Quota() + { + return $this->oImapClient->Quota(); + } + + /** + * @param string $sFolderName + * @param string $sMessageId + * + * @return int|null + */ + public function FindMessageUidByMessageId($sFolderName, $sMessageId) + { + if (0 === \strlen($sMessageId)) + { + throw new \MailSo\Base\Exceptions\InvalidArgumentException(); + } + + $this->oImapClient->FolderExamine($sFolderName); + + $aUids = $this->oImapClient->MessageSimpleSearch( + 'HEADER Message-ID '.$sMessageId, true); + + return \is_array($aUids) && 1 === \count($aUids) && \is_numeric($aUids[0]) ? (int) $aUids[0] : null; + } + + /** + * @param array $aMailFoldersHelper + * @param int $iOptimizationLimit = 0 + * + * @return array + */ + public function folderListOptimization($aMailFoldersHelper, $iOptimizationLimit = 0) + { + // optimization + if (10 < $iOptimizationLimit && \is_array($aMailFoldersHelper) && $iOptimizationLimit < \count($aMailFoldersHelper)) + { + if ($this->oLogger) + { + $this->oLogger->Write('Start optimization (limit:'.$iOptimizationLimit.') for '.\count($aMailFoldersHelper).' folders'); + } + + $iForeachLimit = 1; + + $aFilteredNames = array( + 'inbox', + 'sent', 'send', 'outbox', 'sentmail', 'sendmail', + 'drafts', 'draft', + 'junk', 'spam', 'spambucket', + 'trash', 'bin', 'deleted', + 'archives', 'archive', 'allmail', 'all', + 'starred', 'flagged', 'important', + 'contacts', 'chats' + ); + + $aNewMailFoldersHelper = array(); + + $iCountLimit = $iForeachLimit; + + foreach ($aMailFoldersHelper as $iIndex => /* @var $oImapFolder \MailSo\Mail\Folder */ $oFolder) + { + // mandatory folders + if ($oFolder && \in_array(\str_replace(' ', '', \strtolower($oFolder->NameRaw())), $aFilteredNames)) + { + $aNewMailFoldersHelper[] = $oFolder; + $aMailFoldersHelper[$iIndex] = null; + } + } + + foreach ($aMailFoldersHelper as $iIndex => /* @var $oImapFolder \MailSo\Mail\Folder */ $oFolder) + { + // subscribed folders + if ($oFolder && $oFolder->IsSubscribed()) + { + $aNewMailFoldersHelper[] = $oFolder; + + $aMailFoldersHelper[$iIndex] = null; + $iCountLimit--; + } + + if (0 > $iCountLimit) + { + if ($iOptimizationLimit < \count($aNewMailFoldersHelper)) + { + break; + } + else + { + $iCountLimit = $iForeachLimit; + } + } + } + + $iCountLimit = $iForeachLimit; + if ($iOptimizationLimit >= \count($aNewMailFoldersHelper)) + { + // name filter + foreach ($aMailFoldersHelper as $iIndex => /* @var $oImapFolder \MailSo\Mail\Folder */ $oFolder) + { + if ($oFolder && !\preg_match('/[{}\[\]]/', $oFolder->NameRaw())) + { + $aNewMailFoldersHelper[] = $oFolder; + + $aMailFoldersHelper[$iIndex] = null; + $iCountLimit--; + } + + if (0 > $iCountLimit) + { + if ($iOptimizationLimit < \count($aNewMailFoldersHelper)) + { + break; + } + else + { + $iCountLimit = $iForeachLimit; + } + } + } + } + + $iCountLimit = $iForeachLimit; + if ($iOptimizationLimit >= \count($aNewMailFoldersHelper)) + { + // other + foreach ($aMailFoldersHelper as $iIndex => /* @var $oImapFolder \MailSo\Mail\Folder */ $oFolder) + { + if ($oFolder) + { + $aNewMailFoldersHelper[] = $oFolder; + + $aMailFoldersHelper[$iIndex] = null; + $iCountLimit--; + } + + if (0 > $iCountLimit) + { + if ($iOptimizationLimit < \count($aNewMailFoldersHelper)) + { + break; + } + else + { + $iCountLimit = $iForeachLimit; + } + } + } + } + + $aMailFoldersHelper = $aNewMailFoldersHelper; + + if ($this->oLogger) + { + $this->oLogger->Write('Result optimization: '.\count($aMailFoldersHelper).' folders'); + } + } + + return $aMailFoldersHelper; + } + + /** + * @param string $sParent = '' + * @param string $sListPattern = '*' + * @param bool $bUseListSubscribeStatus = false + * @param int $iOptimizationLimit = 0 + * + * @return \MailSo\Mail\FolderCollection|false + */ + public function Folders($sParent = '', $sListPattern = '*', $bUseListSubscribeStatus = true, $iOptimizationLimit = 0) + { + $oFolderCollection = false; + + $aSubscribedFolders = null; + if ($bUseListSubscribeStatus) + { + try + { + $aSubscribedFolders = $this->oImapClient->FolderSubscribeList($sParent, $sListPattern); + } + catch (\Exception $oException) + { + unset($oException); + } + } + + $aImapSubscribedFoldersHelper = null; + if (\is_array($aSubscribedFolders)) + { + $aImapSubscribedFoldersHelper = array(); + foreach ($aSubscribedFolders as /* @var $oImapFolder \MailSo\Imap\Folder */ $oImapFolder) + { + $aImapSubscribedFoldersHelper[] = $oImapFolder->FullNameRaw(); + } + } + + $aFolders = $this->oImapClient->FolderList($sParent, $sListPattern); + + $bOptimized = false; + $aMailFoldersHelper = null; + + if (\is_array($aFolders)) + { + $aMailFoldersHelper = array(); + + foreach ($aFolders as /* @var $oImapFolder \MailSo\Imap\Folder */ $oImapFolder) + { + $aMailFoldersHelper[] = Folder::NewInstance($oImapFolder, + (null === $aImapSubscribedFoldersHelper || \in_array($oImapFolder->FullNameRaw(), $aImapSubscribedFoldersHelper)) || + $oImapFolder->IsInbox() + ); + } + + $iCount = \count($aMailFoldersHelper); + $aMailFoldersHelper = $this->folderListOptimization($aMailFoldersHelper, $iOptimizationLimit); + + $bOptimized = $iCount !== \count($aMailFoldersHelper); + } + + if (\is_array($aMailFoldersHelper)) + { + $oFolderCollection = FolderCollection::NewInstance(); + $oFolderCollection->InitByUnsortedMailFolderArray($aMailFoldersHelper); + + $oFolderCollection->Optimized = $bOptimized; + } + + if ($oFolderCollection) + { + $oFolderCollection->SortByCallback(function ($oFolderA, $oFolderB) { + $sA = \strtoupper($oFolderA->FullNameRaw()); + $sB = \strtoupper($oFolderB->FullNameRaw()); + switch (true) + { + case 'INBOX' === $sA: + return -1; + case 'INBOX' === $sB: + return 1; + case '[GMAIL]' === $sA: + return -1; + case '[GMAIL]' === $sB: + return 1; + } + + return \strnatcasecmp($oFolderA->FullName(), $oFolderB->FullName()); + }); + + $oNamespace = $this->oImapClient->GetNamespace(); + if ($oNamespace) + { + $oFolderCollection->SetNamespace($oNamespace->GetPersonalNamespace()); + } + + $oFolderCollection->IsThreadsSupported = $this->IsThreadsSupported(); + } + + return $oFolderCollection; + } + + /** + * @param string $sFolderNameInUtf8 + * @param string $sFolderParentFullNameRaw = '' + * @param bool $bSubscribeOnCreation = true + * @param string $sDelimiter = '' + * + * @return \MailSo\Mail\MailClient + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + */ + public function FolderCreate($sFolderNameInUtf8, $sFolderParentFullNameRaw = '', $bSubscribeOnCreation = true, $sDelimiter = '') + { + if (!\MailSo\Base\Validator::NotEmptyString($sFolderNameInUtf8, true) || + !\is_string($sFolderParentFullNameRaw)) + { + throw new \MailSo\Base\Exceptions\InvalidArgumentException(); + } + + $sFolderNameInUtf8 = \trim($sFolderNameInUtf8); + + if (0 === \strlen($sDelimiter) || 0 < \strlen(\trim($sFolderParentFullNameRaw))) + { + $aFolders = $this->oImapClient->FolderList('', 0 === \strlen(\trim($sFolderParentFullNameRaw)) ? 'INBOX' : $sFolderParentFullNameRaw); + if (!\is_array($aFolders) || !isset($aFolders[0])) + { + // TODO + throw new \MailSo\Mail\Exceptions\RuntimeException( + 0 === \strlen(trim($sFolderParentFullNameRaw)) + ? 'Cannot get folder delimiter' + : 'Cannot create folder in non-existen parent folder'); + } + + $sDelimiter = $aFolders[0]->Delimiter(); + if (0 < \strlen($sDelimiter) && 0 < \strlen(\trim($sFolderParentFullNameRaw))) + { + $sFolderParentFullNameRaw .= $sDelimiter; + } + } + + $sFullNameRawToCreate = \MailSo\Base\Utils::ConvertEncoding($sFolderNameInUtf8, + \MailSo\Base\Enumerations\Charset::UTF_8, + \MailSo\Base\Enumerations\Charset::UTF_7_IMAP); + + if (0 < \strlen($sDelimiter) && false !== \strpos($sFullNameRawToCreate, $sDelimiter)) + { + // TODO + throw new \MailSo\Mail\Exceptions\RuntimeException( + 'New folder name contains delimiter'); + } + + $sFullNameRawToCreate = $sFolderParentFullNameRaw.$sFullNameRawToCreate; + + $this->oImapClient->FolderCreate($sFullNameRawToCreate); + + if ($bSubscribeOnCreation) + { + $this->oImapClient->FolderSubscribe($sFullNameRawToCreate); + } + + return $this; + } + + /** + * @param string $sPrevFolderFullNameRaw + * @param string $sNextFolderFullNameInUtf + * @param bool $bSubscribeOnMove = true + * + * @return \MailSo\Mail\MailClient + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + */ + public function FolderMove($sPrevFolderFullNameRaw, $sNextFolderFullNameInUtf, $bSubscribeOnMove = true) + { + return $this->folderModify($sPrevFolderFullNameRaw, $sNextFolderFullNameInUtf, false, $bSubscribeOnMove); + } + + /** + * @param string $sPrevFolderFullNameRaw + * @param string $sNewTopFolderNameInUtf + * @param bool $bSubscribeOnRename = true + * + * @return \MailSo\Mail\MailClient + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + */ + public function FolderRename($sPrevFolderFullNameRaw, $sNewTopFolderNameInUtf, $bSubscribeOnRename = true) + { + return $this->folderModify($sPrevFolderFullNameRaw, $sNewTopFolderNameInUtf, true, $bSubscribeOnRename); + } + + /** + * @param string $sPrevFolderFullNameRaw + * @param string $sNextFolderNameInUtf + * @param bool $bRenameOrMove + * @param bool $bSubscribeOnModify + * + * @return \MailSo\Mail\MailClient + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + */ + public function folderModify($sPrevFolderFullNameRaw, $sNextFolderNameInUtf, $bRenameOrMove, $bSubscribeOnModify) + { + if (0 === \strlen($sPrevFolderFullNameRaw) || 0 === \strlen($sNextFolderNameInUtf)) + { + throw new \MailSo\Base\Exceptions\InvalidArgumentException(); + } + + $aFolders = $this->oImapClient->FolderList('', $sPrevFolderFullNameRaw); + if (!\is_array($aFolders) || !isset($aFolders[0])) + { + // TODO + throw new \MailSo\Mail\Exceptions\RuntimeException('Cannot rename non-existen folder'); + } + + $sDelimiter = $aFolders[0]->Delimiter(); + $iLast = \strrpos($sPrevFolderFullNameRaw, $sDelimiter); + + $mSubscribeFolders = null; + if ($bSubscribeOnModify) + { + $mSubscribeFolders = $this->oImapClient->FolderSubscribeList($sPrevFolderFullNameRaw, '*'); + if (\is_array($mSubscribeFolders) && 0 < count($mSubscribeFolders)) + { + foreach ($mSubscribeFolders as /* @var $oFolder \MailSo\Imap\Folder */ $oFolder) + { + $this->oImapClient->FolderUnSubscribe($oFolder->FullNameRaw()); + } + } + } + + $sNewFolderFullNameRaw = \MailSo\Base\Utils::ConvertEncoding($sNextFolderNameInUtf, + \MailSo\Base\Enumerations\Charset::UTF_8, + \MailSo\Base\Enumerations\Charset::UTF_7_IMAP); + + if($bRenameOrMove) + { + if (0 < \strlen($sDelimiter) && false !== \strpos($sNewFolderFullNameRaw, $sDelimiter)) + { + // TODO + throw new \MailSo\Mail\Exceptions\RuntimeException('New folder name contains delimiter'); + } + + $sFolderParentFullNameRaw = false === $iLast ? '' : \substr($sPrevFolderFullNameRaw, 0, $iLast + 1); + $sNewFolderFullNameRaw = $sFolderParentFullNameRaw.$sNewFolderFullNameRaw; + } + + $this->oImapClient->FolderRename($sPrevFolderFullNameRaw, $sNewFolderFullNameRaw); + + if (\is_array($mSubscribeFolders) && 0 < count($mSubscribeFolders)) + { + foreach ($mSubscribeFolders as /* @var $oFolder \MailSo\Imap\Folder */ $oFolder) + { + $sFolderFullNameRawForResubscrine = $oFolder->FullNameRaw(); + if (0 === \strpos($sFolderFullNameRawForResubscrine, $sPrevFolderFullNameRaw)) + { + $sNewFolderFullNameRawForResubscrine = $sNewFolderFullNameRaw. + \substr($sFolderFullNameRawForResubscrine, \strlen($sPrevFolderFullNameRaw)); + + $this->oImapClient->FolderSubscribe($sNewFolderFullNameRawForResubscrine); + } + } + } + + return $this; + } + + /** + * @param string $sFolderFullNameRaw + * @param bool $bUnsubscribeOnDeletion = true + * + * @return \MailSo\Mail\MailClient + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Mail\Exceptions\RuntimeException + */ + public function FolderDelete($sFolderFullNameRaw, $bUnsubscribeOnDeletion = true) + { + if (0 === \strlen($sFolderFullNameRaw) || 'INBOX' === $sFolderFullNameRaw) + { + throw new \MailSo\Base\Exceptions\InvalidArgumentException(); + } + + $this->oImapClient->FolderExamine($sFolderFullNameRaw); + + $aIndexOrUids = $this->oImapClient->MessageSimpleSearch('ALL'); + if (0 < \count($aIndexOrUids)) + { + throw new \MailSo\Mail\Exceptions\NonEmptyFolder(); + } + + $this->oImapClient->FolderExamine('INBOX'); + + if ($bUnsubscribeOnDeletion) + { + $this->oImapClient->FolderUnSubscribe($sFolderFullNameRaw); + } + + $this->oImapClient->FolderDelete($sFolderFullNameRaw); + + return $this; + } + + /** + * @param string $sFolderFullNameRaw + * + * @return \MailSo\Mail\MailClient + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + */ + public function FolderClear($sFolderFullNameRaw) + { + $this->oImapClient->FolderSelect($sFolderFullNameRaw); + + $oFolderInformation = $this->oImapClient->FolderCurrentInformation(); + if ($oFolderInformation && $oFolderInformation->Exists && 0 < $oFolderInformation->Exists) // STATUS? + { + $this->oImapClient->MessageStoreFlag('1:*', false, + array(\MailSo\Imap\Enumerations\MessageFlag::DELETED), + \MailSo\Imap\Enumerations\StoreAction::ADD_FLAGS_SILENT + ); + + $this->oImapClient->MessageExpunge(); + } + + return $this; + } + + /** + * @param string $sFolderFullNameRaw + * @param bool $bSubscribe + * + * @return \MailSo\Mail\MailClient + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + */ + public function FolderSubscribe($sFolderFullNameRaw, $bSubscribe) + { + if (0 === \strlen($sFolderFullNameRaw)) + { + throw new \MailSo\Base\Exceptions\InvalidArgumentException(); + } + + $this->oImapClient->{($bSubscribe) ? 'FolderSubscribe' : 'FolderUnSubscribe'}($sFolderFullNameRaw); + + return $this; + } + + /** + * @param \MailSo\Log\Logger $oLogger + * + * @return \MailSo\Mail\MailClient + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + */ + public function SetLogger($oLogger) + { + if (!($oLogger instanceof \MailSo\Log\Logger)) + { + throw new \MailSo\Base\Exceptions\InvalidArgumentException(); + } + + $this->oLogger = $oLogger; + $this->oImapClient->SetLogger($this->oLogger); + + return $this; + } +} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mail/Message.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mail/Message.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mail/Message.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mail/Message.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mail/MessageCollection.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mail/MessageCollection.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mail/MessageCollection.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mail/MessageCollection.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/MailSo.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/MailSo.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/MailSo.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/MailSo.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mime/Attachment.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mime/Attachment.php similarity index 94% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mime/Attachment.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mime/Attachment.php index 4d15555d94a9f77f793781f959f710dc164055ed..ed1c2acea691625c92ae8d7cb9ff4bb0230189ad 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mime/Attachment.php +++ b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mime/Attachment.php @@ -1,197 +1,197 @@ -rResource = $rResource; - $this->sFileName = $sFileName; - $this->iFileSize = $iFileSize; - $this->bIsInline = $bIsInline; - $this->bIsLinked = $bIsLinked; - $this->sCID = $sCID; - $this->aCustomContentTypeParams = $aCustomContentTypeParams; - $this->sContentLocation = $sContentLocation; - } - - /** - * @param resource $rResource - * @param string $sFileName = '' - * @param int $iFileSize = 0 - * @param bool $bIsInline = false - * @param bool $bIsLinked = false - * @param string $sCID = '' - * @param array $aCustomContentTypeParams = array() - * @param string $sContentLocation = '' - * - * @return \MailSo\Mime\Attachment - */ - public static function NewInstance($rResource, $sFileName = '', $iFileSize = 0, $bIsInline = false, - $bIsLinked = false, $sCID = '', $aCustomContentTypeParams = array(), $sContentLocation = '') - { - return new self($rResource, $sFileName, $iFileSize, $bIsInline, $bIsLinked, $sCID, $aCustomContentTypeParams, $sContentLocation); - } - - /** - * @return resource - */ - public function Resource() - { - return $this->rResource; - } - - /** - * @return string - */ - public function ContentType() - { - return \MailSo\Base\Utils::MimeContentType($this->sFileName); - } - - /** - * @return array - */ - public function CustomContentTypeParams() - { - return $this->aCustomContentTypeParams; - } - - /** - * @return string - */ - public function CID() - { - return $this->sCID; - } - - /** - * @return string - */ - public function ContentLocation() - { - return $this->sContentLocation; - } - - /** - * @return string - */ - public function FileName() - { - return $this->sFileName; - } - - /** - * @return int - */ - public function FileSize() - { - return $this->iFileSize; - } - - /** - * @return bool - */ - public function IsInline() - { - return $this->bIsInline; - } - - /** - * @return bool - */ - public function IsImage() - { - return 'image' === \MailSo\Base\Utils::ContentTypeType($this->ContentType(), $this->FileName()); - } - - /** - * @return bool - */ - public function IsArchive() - { - return 'archive' === \MailSo\Base\Utils::ContentTypeType($this->ContentType(), $this->FileName()); - } - - /** - * @return bool - */ - public function IsPdf() - { - return 'pdf' === \MailSo\Base\Utils::ContentTypeType($this->ContentType(), $this->FileName()); - } - - /** - * @return bool - */ - public function IsDoc() - { - return 'doc' === \MailSo\Base\Utils::ContentTypeType($this->ContentType(), $this->FileName()); - } - - /** - * @return bool - */ - public function IsLinked() - { - return $this->bIsLinked && 0 < \strlen($this->sCID); - } +rResource = $rResource; + $this->sFileName = $sFileName; + $this->iFileSize = $iFileSize; + $this->bIsInline = $bIsInline; + $this->bIsLinked = $bIsLinked; + $this->sCID = $sCID; + $this->aCustomContentTypeParams = $aCustomContentTypeParams; + $this->sContentLocation = $sContentLocation; + } + + /** + * @param resource $rResource + * @param string $sFileName = '' + * @param int $iFileSize = 0 + * @param bool $bIsInline = false + * @param bool $bIsLinked = false + * @param string $sCID = '' + * @param array $aCustomContentTypeParams = array() + * @param string $sContentLocation = '' + * + * @return \MailSo\Mime\Attachment + */ + public static function NewInstance($rResource, $sFileName = '', $iFileSize = 0, $bIsInline = false, + $bIsLinked = false, $sCID = '', $aCustomContentTypeParams = array(), $sContentLocation = '') + { + return new self($rResource, $sFileName, $iFileSize, $bIsInline, $bIsLinked, $sCID, $aCustomContentTypeParams, $sContentLocation); + } + + /** + * @return resource + */ + public function Resource() + { + return $this->rResource; + } + + /** + * @return string + */ + public function ContentType() + { + return \MailSo\Base\Utils::MimeContentType($this->sFileName); + } + + /** + * @return array + */ + public function CustomContentTypeParams() + { + return $this->aCustomContentTypeParams; + } + + /** + * @return string + */ + public function CID() + { + return $this->sCID; + } + + /** + * @return string + */ + public function ContentLocation() + { + return $this->sContentLocation; + } + + /** + * @return string + */ + public function FileName() + { + return $this->sFileName; + } + + /** + * @return int + */ + public function FileSize() + { + return $this->iFileSize; + } + + /** + * @return bool + */ + public function IsInline() + { + return $this->bIsInline; + } + + /** + * @return bool + */ + public function IsImage() + { + return 'image' === \MailSo\Base\Utils::ContentTypeType($this->ContentType(), $this->FileName()); + } + + /** + * @return bool + */ + public function IsArchive() + { + return 'archive' === \MailSo\Base\Utils::ContentTypeType($this->ContentType(), $this->FileName()); + } + + /** + * @return bool + */ + public function IsPdf() + { + return 'pdf' === \MailSo\Base\Utils::ContentTypeType($this->ContentType(), $this->FileName()); + } + + /** + * @return bool + */ + public function IsDoc() + { + return 'doc' === \MailSo\Base\Utils::ContentTypeType($this->ContentType(), $this->FileName()); + } + + /** + * @return bool + */ + public function IsLinked() + { + return $this->bIsLinked && 0 < \strlen($this->sCID); + } } \ No newline at end of file diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mime/AttachmentCollection.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mime/AttachmentCollection.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mime/AttachmentCollection.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mime/AttachmentCollection.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mime/Email.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mime/Email.php similarity index 95% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mime/Email.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mime/Email.php index 9dd393f5d0417192cf9e352362779f423bf81477..6347f0f813255f3dc202f85ef13c08c1f9102792 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mime/Email.php +++ b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mime/Email.php @@ -1,315 +1,315 @@ -sEmail = \MailSo\Base\Utils::IdnToAscii( - \MailSo\Base\Utils::Trim($sEmail), true); - - $this->sDisplayName = \MailSo\Base\Utils::Trim($sDisplayName); - - $this->sDkimStatus = \MailSo\Mime\Enumerations\DkimStatus::NONE; - $this->sDkimValue = ''; - } - - /** - * @param string $sEmail - * @param string $sDisplayName = '' - * - * @return \MailSo\Mime\Email - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - */ - public static function NewInstance($sEmail, $sDisplayName = '') - { - return new self($sEmail, $sDisplayName); - } - - /** - * @param string $sEmailAddress - * @return \MailSo\Mime\Email - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - */ - public static function Parse($sEmailAddress) - { - $sEmailAddress = \MailSo\Base\Utils::Trim($sEmailAddress); - if (!\MailSo\Base\Validator::NotEmptyString($sEmailAddress, true)) - { - throw new \MailSo\Base\Exceptions\InvalidArgumentException(); - } - - $sName = ''; - $sEmail = ''; - $sComment = ''; - - $bInName = false; - $bInAddress = false; - $bInComment = false; - - $iStartIndex = 0; - $iEndIndex = 0; - $iCurrentIndex = 0; - - while ($iCurrentIndex < \strlen($sEmailAddress)) - { - switch ($sEmailAddress{$iCurrentIndex}) - { -// case '\'': - case '"': -// $sQuoteChar = $sEmailAddress{$iCurrentIndex}; - if ((!$bInName) && (!$bInAddress) && (!$bInComment)) - { - $bInName = true; - $iStartIndex = $iCurrentIndex; - } - else if ((!$bInAddress) && (!$bInComment)) - { - $iEndIndex = $iCurrentIndex; - $sName = \substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1); - $sEmailAddress = \substr_replace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1); - $iEndIndex = 0; - $iCurrentIndex = 0; - $iStartIndex = 0; - $bInName = false; - } - break; - case '<': - if ((!$bInName) && (!$bInAddress) && (!$bInComment)) - { - if ($iCurrentIndex > 0 && \strlen($sName) === 0) - { - $sName = \substr($sEmailAddress, 0, $iCurrentIndex); - } - - $bInAddress = true; - $iStartIndex = $iCurrentIndex; - } - break; - case '>': - if ($bInAddress) - { - $iEndIndex = $iCurrentIndex; - $sEmail = \substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1); - $sEmailAddress = \substr_replace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1); - $iEndIndex = 0; - $iCurrentIndex = 0; - $iStartIndex = 0; - $bInAddress = false; - } - break; - case '(': - if ((!$bInName) && (!$bInAddress) && (!$bInComment)) - { - $bInComment = true; - $iStartIndex = $iCurrentIndex; - } - break; - case ')': - if ($bInComment) - { - $iEndIndex = $iCurrentIndex; - $sComment = \substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1); - $sEmailAddress = \substr_replace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1); - $iEndIndex = 0; - $iCurrentIndex = 0; - $iStartIndex = 0; - $bInComment = false; - } - break; - case '\\': - $iCurrentIndex++; - break; - } - - $iCurrentIndex++; - } - - if (\strlen($sEmail) === 0) - { - $aRegs = array(''); - if (\preg_match('/[^@\s]+@\S+/i', $sEmailAddress, $aRegs) && isset($aRegs[0])) - { - $sEmail = $aRegs[0]; - } - else - { - $sName = $sEmailAddress; - } - } - - if ((\strlen($sEmail) > 0) && (\strlen($sName) == 0) && (\strlen($sComment) == 0)) - { - $sName = \str_replace($sEmail, '', $sEmailAddress); - } - - $sEmail = \trim(\trim($sEmail), '<>'); - $sEmail = \rtrim(\trim($sEmail), '.'); - $sEmail = \trim($sEmail); - - $sName = \trim(\trim($sName), '"'); - $sName = \trim($sName, '\''); - $sComment = \trim(\trim($sComment), '()'); - - // Remove backslash - $sName = \preg_replace('/\\\\(.)/s', '$1', $sName); - $sComment = \preg_replace('/\\\\(.)/s', '$1', $sComment); - - return Email::NewInstance($sEmail, $sName); - } - - /** - * @param bool $bIdn = false - * - * @return string - */ - public function GetEmail($bIdn = false) - { - return $bIdn ? \MailSo\Base\Utils::IdnToUtf8($this->sEmail) : $this->sEmail; - } - - /** - * @return string - */ - public function GetDisplayName() - { - return $this->sDisplayName; - } - - /** - * @return string - */ - public function GetDkimStatus() - { - return $this->sDkimStatus; - } - - /** - * @return string - */ - public function GetDkimValue() - { - return $this->sDkimValue; - } - - /** - * @return string - */ - public function GetAccountName() - { - return \MailSo\Base\Utils::GetAccountNameFromEmail($this->GetEmail(false)); - } - - /** - * @param bool $bIdn = false - * - * @return string - */ - public function GetDomain($bIdn = false) - { - return \MailSo\Base\Utils::GetDomainFromEmail($this->GetEmail($bIdn)); - } - - /** - * @param string $sDkimStatus - * @param string $sDkimValue = '' - */ - public function SetDkimStatusAndValue($sDkimStatus, $sDkimValue = '') - { - $this->sDkimStatus = \MailSo\Mime\Enumerations\DkimStatus::normalizeValue($sDkimStatus); - $this->sDkimValue = $sDkimValue; - } - - /** - * @param bool $bIdn = false - * @param bool $bDkim = true - * - * @return array - */ - public function ToArray($bIdn = false, $bDkim = true) - { - return $bDkim ? - array($this->sDisplayName, $this->GetEmail($bIdn), $this->sDkimStatus, $this->sDkimValue) : - array($this->sDisplayName, $this->GetEmail($bIdn)); - } - - /** - * @param bool $bConvertSpecialsName = false - * @param bool $bIdn = false - * - * @return string - */ - public function ToString($bConvertSpecialsName = false, $bIdn = false) - { - $sReturn = ''; - - $sDisplayName = \str_replace('"', '\"', $this->sDisplayName); - if ($bConvertSpecialsName) - { - $sDisplayName = 0 === \strlen($sDisplayName) ? '' : \MailSo\Base\Utils::EncodeUnencodedValue( - \MailSo\Base\Enumerations\Encoding::BASE64_SHORT, - $sDisplayName); - } - - $sDisplayName = 0 === \strlen($sDisplayName) ? '' : '"'.$sDisplayName.'"'; - if (0 < \strlen($this->sEmail)) - { - $sReturn = $this->GetEmail($bIdn); - if (0 < \strlen($sDisplayName)) - { - $sReturn = $sDisplayName.' <'.$sReturn.'>'; - } - } - - return \trim($sReturn); - } -} +sEmail = \MailSo\Base\Utils::IdnToAscii( + \MailSo\Base\Utils::Trim($sEmail), true); + + $this->sDisplayName = \MailSo\Base\Utils::Trim($sDisplayName); + + $this->sDkimStatus = \MailSo\Mime\Enumerations\DkimStatus::NONE; + $this->sDkimValue = ''; + } + + /** + * @param string $sEmail + * @param string $sDisplayName = '' + * + * @return \MailSo\Mime\Email + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + */ + public static function NewInstance($sEmail, $sDisplayName = '') + { + return new self($sEmail, $sDisplayName); + } + + /** + * @param string $sEmailAddress + * @return \MailSo\Mime\Email + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + */ + public static function Parse($sEmailAddress) + { + $sEmailAddress = \MailSo\Base\Utils::Trim($sEmailAddress); + if (!\MailSo\Base\Validator::NotEmptyString($sEmailAddress, true)) + { + throw new \MailSo\Base\Exceptions\InvalidArgumentException(); + } + + $sName = ''; + $sEmail = ''; + $sComment = ''; + + $bInName = false; + $bInAddress = false; + $bInComment = false; + + $iStartIndex = 0; + $iEndIndex = 0; + $iCurrentIndex = 0; + + while ($iCurrentIndex < \strlen($sEmailAddress)) + { + switch ($sEmailAddress{$iCurrentIndex}) + { +// case '\'': + case '"': +// $sQuoteChar = $sEmailAddress{$iCurrentIndex}; + if ((!$bInName) && (!$bInAddress) && (!$bInComment)) + { + $bInName = true; + $iStartIndex = $iCurrentIndex; + } + else if ((!$bInAddress) && (!$bInComment)) + { + $iEndIndex = $iCurrentIndex; + $sName = \substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1); + $sEmailAddress = \substr_replace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1); + $iEndIndex = 0; + $iCurrentIndex = 0; + $iStartIndex = 0; + $bInName = false; + } + break; + case '<': + if ((!$bInName) && (!$bInAddress) && (!$bInComment)) + { + if ($iCurrentIndex > 0 && \strlen($sName) === 0) + { + $sName = \substr($sEmailAddress, 0, $iCurrentIndex); + } + + $bInAddress = true; + $iStartIndex = $iCurrentIndex; + } + break; + case '>': + if ($bInAddress) + { + $iEndIndex = $iCurrentIndex; + $sEmail = \substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1); + $sEmailAddress = \substr_replace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1); + $iEndIndex = 0; + $iCurrentIndex = 0; + $iStartIndex = 0; + $bInAddress = false; + } + break; + case '(': + if ((!$bInName) && (!$bInAddress) && (!$bInComment)) + { + $bInComment = true; + $iStartIndex = $iCurrentIndex; + } + break; + case ')': + if ($bInComment) + { + $iEndIndex = $iCurrentIndex; + $sComment = \substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1); + $sEmailAddress = \substr_replace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1); + $iEndIndex = 0; + $iCurrentIndex = 0; + $iStartIndex = 0; + $bInComment = false; + } + break; + case '\\': + $iCurrentIndex++; + break; + } + + $iCurrentIndex++; + } + + if (\strlen($sEmail) === 0) + { + $aRegs = array(''); + if (\preg_match('/[^@\s]+@\S+/i', $sEmailAddress, $aRegs) && isset($aRegs[0])) + { + $sEmail = $aRegs[0]; + } + else + { + $sName = $sEmailAddress; + } + } + + if ((\strlen($sEmail) > 0) && (\strlen($sName) == 0) && (\strlen($sComment) == 0)) + { + $sName = \str_replace($sEmail, '', $sEmailAddress); + } + + $sEmail = \trim(\trim($sEmail), '<>'); + $sEmail = \rtrim(\trim($sEmail), '.'); + $sEmail = \trim($sEmail); + + $sName = \trim(\trim($sName), '"'); + $sName = \trim($sName, '\''); + $sComment = \trim(\trim($sComment), '()'); + + // Remove backslash + $sName = \preg_replace('/\\\\(.)/s', '$1', $sName); + $sComment = \preg_replace('/\\\\(.)/s', '$1', $sComment); + + return Email::NewInstance($sEmail, $sName); + } + + /** + * @param bool $bIdn = false + * + * @return string + */ + public function GetEmail($bIdn = false) + { + return $bIdn ? \MailSo\Base\Utils::IdnToUtf8($this->sEmail) : $this->sEmail; + } + + /** + * @return string + */ + public function GetDisplayName() + { + return $this->sDisplayName; + } + + /** + * @return string + */ + public function GetDkimStatus() + { + return $this->sDkimStatus; + } + + /** + * @return string + */ + public function GetDkimValue() + { + return $this->sDkimValue; + } + + /** + * @return string + */ + public function GetAccountName() + { + return \MailSo\Base\Utils::GetAccountNameFromEmail($this->GetEmail(false)); + } + + /** + * @param bool $bIdn = false + * + * @return string + */ + public function GetDomain($bIdn = false) + { + return \MailSo\Base\Utils::GetDomainFromEmail($this->GetEmail($bIdn)); + } + + /** + * @param string $sDkimStatus + * @param string $sDkimValue = '' + */ + public function SetDkimStatusAndValue($sDkimStatus, $sDkimValue = '') + { + $this->sDkimStatus = \MailSo\Mime\Enumerations\DkimStatus::normalizeValue($sDkimStatus); + $this->sDkimValue = $sDkimValue; + } + + /** + * @param bool $bIdn = false + * @param bool $bDkim = true + * + * @return array + */ + public function ToArray($bIdn = false, $bDkim = true) + { + return $bDkim ? + array($this->sDisplayName, $this->GetEmail($bIdn), $this->sDkimStatus, $this->sDkimValue) : + array($this->sDisplayName, $this->GetEmail($bIdn)); + } + + /** + * @param bool $bConvertSpecialsName = false + * @param bool $bIdn = false + * + * @return string + */ + public function ToString($bConvertSpecialsName = false, $bIdn = false) + { + $sReturn = ''; + + $sDisplayName = \str_replace('"', '\"', $this->sDisplayName); + if ($bConvertSpecialsName) + { + $sDisplayName = 0 === \strlen($sDisplayName) ? '' : \MailSo\Base\Utils::EncodeUnencodedValue( + \MailSo\Base\Enumerations\Encoding::BASE64_SHORT, + $sDisplayName); + } + + $sDisplayName = 0 === \strlen($sDisplayName) ? '' : '"'.$sDisplayName.'"'; + if (0 < \strlen($this->sEmail)) + { + $sReturn = $this->GetEmail($bIdn); + if (0 < \strlen($sDisplayName)) + { + $sReturn = $sDisplayName.' <'.$sReturn.'>'; + } + } + + return \trim($sReturn); + } +} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mime/EmailCollection.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mime/EmailCollection.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mime/EmailCollection.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mime/EmailCollection.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mime/EmailDep.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mime/EmailDep.php similarity index 95% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mime/EmailDep.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mime/EmailDep.php index 64173bed359adca51f07c560605a7e34997ab6d5..7a923faee2a6f91054415c3f8fd74e6c82aaf009 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mime/EmailDep.php +++ b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mime/EmailDep.php @@ -1,339 +1,339 @@ -sEmail = \MailSo\Base\Utils::IdnToAscii( - \MailSo\Base\Utils::Trim($sEmail), true); - - $this->sDisplayName = \MailSo\Base\Utils::Trim($sDisplayName); - $this->sRemark = \MailSo\Base\Utils::Trim($sRemark); - - $this->sDkimStatus = \MailSo\Mime\Enumerations\DkimStatus::NONE; - $this->sDkimValue = ''; - } - - /** - * @param string $sEmail - * @param string $sDisplayName = '' - * @param string $sRemark = '' - * - * @return \MailSo\Mime\Email - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - */ - public static function NewInstance($sEmail, $sDisplayName = '', $sRemark = '') - { - return new self($sEmail, $sDisplayName, $sRemark); - } - - /** - * @param string $sEmailAddress - * @return \MailSo\Mime\Email - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - */ - public static function Parse($sEmailAddress) - { - $sEmailAddress = \MailSo\Base\Utils::Trim($sEmailAddress); - if (!\MailSo\Base\Validator::NotEmptyString($sEmailAddress, true)) - { - throw new \MailSo\Base\Exceptions\InvalidArgumentException(); - } - - $sName = ''; - $sEmail = ''; - $sComment = ''; - - $bInName = false; - $bInAddress = false; - $bInComment = false; - - $iStartIndex = 0; - $iEndIndex = 0; - $iCurrentIndex = 0; - - while ($iCurrentIndex < \strlen($sEmailAddress)) - { - switch ($sEmailAddress{$iCurrentIndex}) - { -// case '\'': - case '"': -// $sQuoteChar = $sEmailAddress{$iCurrentIndex}; - if ((!$bInName) && (!$bInAddress) && (!$bInComment)) - { - $bInName = true; - $iStartIndex = $iCurrentIndex; - } - else if ((!$bInAddress) && (!$bInComment)) - { - $iEndIndex = $iCurrentIndex; - $sName = \substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1); - $sEmailAddress = \substr_replace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1); - $iEndIndex = 0; - $iCurrentIndex = 0; - $iStartIndex = 0; - $bInName = false; - } - break; - case '<': - if ((!$bInName) && (!$bInAddress) && (!$bInComment)) - { - if ($iCurrentIndex > 0 && \strlen($sName) === 0) - { - $sName = \substr($sEmailAddress, 0, $iCurrentIndex); - } - - $bInAddress = true; - $iStartIndex = $iCurrentIndex; - } - break; - case '>': - if ($bInAddress) - { - $iEndIndex = $iCurrentIndex; - $sEmail = \substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1); - $sEmailAddress = \substr_replace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1); - $iEndIndex = 0; - $iCurrentIndex = 0; - $iStartIndex = 0; - $bInAddress = false; - } - break; - case '(': - if ((!$bInName) && (!$bInAddress) && (!$bInComment)) - { - $bInComment = true; - $iStartIndex = $iCurrentIndex; - } - break; - case ')': - if ($bInComment) - { - $iEndIndex = $iCurrentIndex; - $sComment = \substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1); - $sEmailAddress = \substr_replace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1); - $iEndIndex = 0; - $iCurrentIndex = 0; - $iStartIndex = 0; - $bInComment = false; - } - break; - case '\\': - $iCurrentIndex++; - break; - } - - $iCurrentIndex++; - } - - if (\strlen($sEmail) === 0) - { - $aRegs = array(''); - if (\preg_match('/[^@\s]+@\S+/i', $sEmailAddress, $aRegs) && isset($aRegs[0])) - { - $sEmail = $aRegs[0]; - } - else - { - $sName = $sEmailAddress; - } - } - - if ((\strlen($sEmail) > 0) && (\strlen($sName) == 0) && (\strlen($sComment) == 0)) - { - $sName = \str_replace($sEmail, '', $sEmailAddress); - } - - $sEmail = \trim(\trim($sEmail), '<>'); - $sEmail = \rtrim(\trim($sEmail), '.'); - $sEmail = \trim($sEmail); - - $sName = \trim(\trim($sName), '"'); - $sName = \trim($sName, '\''); - $sComment = \trim(\trim($sComment), '()'); - - // Remove backslash - $sName = \preg_replace('/\\\\(.)/s', '$1', $sName); - $sComment = \preg_replace('/\\\\(.)/s', '$1', $sComment); - - return Email::NewInstance($sEmail, $sName, $sComment); - } - - /** - * @param bool $bIdn = false - * - * @return string - */ - public function GetEmail($bIdn = false) - { - return $bIdn ? \MailSo\Base\Utils::IdnToUtf8($this->sEmail) : $this->sEmail; - } - - /** - * @return string - */ - public function GetDisplayName() - { - return $this->sDisplayName; - } - - /** - * @return string - */ - public function GetRemark() - { - return $this->sRemark; - } - - /** - * @return string - */ - public function GetDkimStatus() - { - return $this->sDkimStatus; - } - - /** - * @return string - */ - public function GetDkimValue() - { - return $this->sDkimValue; - } - - /** - * @return string - */ - public function GetAccountName() - { - return \MailSo\Base\Utils::GetAccountNameFromEmail($this->GetEmail(false)); - } - - /** - * @param bool $bIdn = false - * - * @return string - */ - public function GetDomain($bIdn = false) - { - return \MailSo\Base\Utils::GetDomainFromEmail($this->GetEmail($bIdn)); - } - - /** - * @param string $sDkimStatus - * @param string $sDkimValue = '' - */ - public function SetDkimStatusAndValue($sDkimStatus, $sDkimValue = '') - { - $this->sDkimStatus = \MailSo\Mime\Enumerations\DkimStatus::normalizeValue($sDkimStatus); - $this->sDkimValue = $sDkimValue; - } - - /** - * @param bool $bIdn = false - * @param bool $bDkim = true - * - * @return array - */ - public function ToArray($bIdn = false, $bDkim = true) - { - return $bDkim ? array($this->sDisplayName, $this->GetEmail($bIdn), $this->sRemark, $this->sDkimStatus, $this->sDkimValue) : - array($this->sDisplayName, $this->GetEmail($bIdn), $this->sRemark); - } - - /** - * @param bool $bConvertSpecialsName = false - * @param bool $bIdn = false - * - * @return string - */ - public function ToString($bConvertSpecialsName = false, $bIdn = false) - { - $sReturn = ''; - - $sRemark = \str_replace(')', '\)', $this->sRemark); - $sDisplayName = \str_replace('"', '\"', $this->sDisplayName); - - if ($bConvertSpecialsName) - { - $sDisplayName = 0 === \strlen($sDisplayName) ? '' : \MailSo\Base\Utils::EncodeUnencodedValue( - \MailSo\Base\Enumerations\Encoding::BASE64_SHORT, - $sDisplayName); - - $sRemark = 0 === \strlen($sRemark) ? '' : \MailSo\Base\Utils::EncodeUnencodedValue( - \MailSo\Base\Enumerations\Encoding::BASE64_SHORT, - $sRemark); - } - - $sDisplayName = 0 === \strlen($sDisplayName) ? '' : '"'.$sDisplayName.'"'; - $sRemark = 0 === \strlen($sRemark) ? '' : '('.$sRemark.')'; - - if (0 < \strlen($this->sEmail)) - { - $sReturn = $this->GetEmail($bIdn); - if (0 < \strlen($sDisplayName.$sRemark)) - { - $sReturn = $sDisplayName.' <'.$sReturn.'> '.$sRemark; - } - } - - return \trim($sReturn); - } -} +sEmail = \MailSo\Base\Utils::IdnToAscii( + \MailSo\Base\Utils::Trim($sEmail), true); + + $this->sDisplayName = \MailSo\Base\Utils::Trim($sDisplayName); + $this->sRemark = \MailSo\Base\Utils::Trim($sRemark); + + $this->sDkimStatus = \MailSo\Mime\Enumerations\DkimStatus::NONE; + $this->sDkimValue = ''; + } + + /** + * @param string $sEmail + * @param string $sDisplayName = '' + * @param string $sRemark = '' + * + * @return \MailSo\Mime\Email + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + */ + public static function NewInstance($sEmail, $sDisplayName = '', $sRemark = '') + { + return new self($sEmail, $sDisplayName, $sRemark); + } + + /** + * @param string $sEmailAddress + * @return \MailSo\Mime\Email + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + */ + public static function Parse($sEmailAddress) + { + $sEmailAddress = \MailSo\Base\Utils::Trim($sEmailAddress); + if (!\MailSo\Base\Validator::NotEmptyString($sEmailAddress, true)) + { + throw new \MailSo\Base\Exceptions\InvalidArgumentException(); + } + + $sName = ''; + $sEmail = ''; + $sComment = ''; + + $bInName = false; + $bInAddress = false; + $bInComment = false; + + $iStartIndex = 0; + $iEndIndex = 0; + $iCurrentIndex = 0; + + while ($iCurrentIndex < \strlen($sEmailAddress)) + { + switch ($sEmailAddress{$iCurrentIndex}) + { +// case '\'': + case '"': +// $sQuoteChar = $sEmailAddress{$iCurrentIndex}; + if ((!$bInName) && (!$bInAddress) && (!$bInComment)) + { + $bInName = true; + $iStartIndex = $iCurrentIndex; + } + else if ((!$bInAddress) && (!$bInComment)) + { + $iEndIndex = $iCurrentIndex; + $sName = \substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1); + $sEmailAddress = \substr_replace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1); + $iEndIndex = 0; + $iCurrentIndex = 0; + $iStartIndex = 0; + $bInName = false; + } + break; + case '<': + if ((!$bInName) && (!$bInAddress) && (!$bInComment)) + { + if ($iCurrentIndex > 0 && \strlen($sName) === 0) + { + $sName = \substr($sEmailAddress, 0, $iCurrentIndex); + } + + $bInAddress = true; + $iStartIndex = $iCurrentIndex; + } + break; + case '>': + if ($bInAddress) + { + $iEndIndex = $iCurrentIndex; + $sEmail = \substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1); + $sEmailAddress = \substr_replace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1); + $iEndIndex = 0; + $iCurrentIndex = 0; + $iStartIndex = 0; + $bInAddress = false; + } + break; + case '(': + if ((!$bInName) && (!$bInAddress) && (!$bInComment)) + { + $bInComment = true; + $iStartIndex = $iCurrentIndex; + } + break; + case ')': + if ($bInComment) + { + $iEndIndex = $iCurrentIndex; + $sComment = \substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1); + $sEmailAddress = \substr_replace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1); + $iEndIndex = 0; + $iCurrentIndex = 0; + $iStartIndex = 0; + $bInComment = false; + } + break; + case '\\': + $iCurrentIndex++; + break; + } + + $iCurrentIndex++; + } + + if (\strlen($sEmail) === 0) + { + $aRegs = array(''); + if (\preg_match('/[^@\s]+@\S+/i', $sEmailAddress, $aRegs) && isset($aRegs[0])) + { + $sEmail = $aRegs[0]; + } + else + { + $sName = $sEmailAddress; + } + } + + if ((\strlen($sEmail) > 0) && (\strlen($sName) == 0) && (\strlen($sComment) == 0)) + { + $sName = \str_replace($sEmail, '', $sEmailAddress); + } + + $sEmail = \trim(\trim($sEmail), '<>'); + $sEmail = \rtrim(\trim($sEmail), '.'); + $sEmail = \trim($sEmail); + + $sName = \trim(\trim($sName), '"'); + $sName = \trim($sName, '\''); + $sComment = \trim(\trim($sComment), '()'); + + // Remove backslash + $sName = \preg_replace('/\\\\(.)/s', '$1', $sName); + $sComment = \preg_replace('/\\\\(.)/s', '$1', $sComment); + + return Email::NewInstance($sEmail, $sName, $sComment); + } + + /** + * @param bool $bIdn = false + * + * @return string + */ + public function GetEmail($bIdn = false) + { + return $bIdn ? \MailSo\Base\Utils::IdnToUtf8($this->sEmail) : $this->sEmail; + } + + /** + * @return string + */ + public function GetDisplayName() + { + return $this->sDisplayName; + } + + /** + * @return string + */ + public function GetRemark() + { + return $this->sRemark; + } + + /** + * @return string + */ + public function GetDkimStatus() + { + return $this->sDkimStatus; + } + + /** + * @return string + */ + public function GetDkimValue() + { + return $this->sDkimValue; + } + + /** + * @return string + */ + public function GetAccountName() + { + return \MailSo\Base\Utils::GetAccountNameFromEmail($this->GetEmail(false)); + } + + /** + * @param bool $bIdn = false + * + * @return string + */ + public function GetDomain($bIdn = false) + { + return \MailSo\Base\Utils::GetDomainFromEmail($this->GetEmail($bIdn)); + } + + /** + * @param string $sDkimStatus + * @param string $sDkimValue = '' + */ + public function SetDkimStatusAndValue($sDkimStatus, $sDkimValue = '') + { + $this->sDkimStatus = \MailSo\Mime\Enumerations\DkimStatus::normalizeValue($sDkimStatus); + $this->sDkimValue = $sDkimValue; + } + + /** + * @param bool $bIdn = false + * @param bool $bDkim = true + * + * @return array + */ + public function ToArray($bIdn = false, $bDkim = true) + { + return $bDkim ? array($this->sDisplayName, $this->GetEmail($bIdn), $this->sRemark, $this->sDkimStatus, $this->sDkimValue) : + array($this->sDisplayName, $this->GetEmail($bIdn), $this->sRemark); + } + + /** + * @param bool $bConvertSpecialsName = false + * @param bool $bIdn = false + * + * @return string + */ + public function ToString($bConvertSpecialsName = false, $bIdn = false) + { + $sReturn = ''; + + $sRemark = \str_replace(')', '\)', $this->sRemark); + $sDisplayName = \str_replace('"', '\"', $this->sDisplayName); + + if ($bConvertSpecialsName) + { + $sDisplayName = 0 === \strlen($sDisplayName) ? '' : \MailSo\Base\Utils::EncodeUnencodedValue( + \MailSo\Base\Enumerations\Encoding::BASE64_SHORT, + $sDisplayName); + + $sRemark = 0 === \strlen($sRemark) ? '' : \MailSo\Base\Utils::EncodeUnencodedValue( + \MailSo\Base\Enumerations\Encoding::BASE64_SHORT, + $sRemark); + } + + $sDisplayName = 0 === \strlen($sDisplayName) ? '' : '"'.$sDisplayName.'"'; + $sRemark = 0 === \strlen($sRemark) ? '' : '('.$sRemark.')'; + + if (0 < \strlen($this->sEmail)) + { + $sReturn = $this->GetEmail($bIdn); + if (0 < \strlen($sDisplayName.$sRemark)) + { + $sReturn = $sDisplayName.' <'.$sReturn.'> '.$sRemark; + } + } + + return \trim($sReturn); + } +} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mime/Enumerations/Constants.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mime/Enumerations/Constants.php similarity index 94% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mime/Enumerations/Constants.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mime/Enumerations/Constants.php index 7f52ee8909dccb153a56784d4af29b292d6c6b18..41da58188336178fe93c674daab378bb3bf58897 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mime/Enumerations/Constants.php +++ b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mime/Enumerations/Constants.php @@ -1,25 +1,25 @@ -sRawHeaders = ''; - $this->sParentCharset = ''; - - if (0 < \strlen($sRawHeaders)) - { - $this->Parse($sRawHeaders, $bStoreRawHeaders); - } - } - - /** - * @param string $sRawHeaders = '' - * @param bool $bStoreRawHeaders = true - * - * @return \MailSo\Mime\HeaderCollection - */ - public static function NewInstance($sRawHeaders = '', $bStoreRawHeaders = true) - { - return new self($sRawHeaders, $bStoreRawHeaders); - } - - /** - * @param string $sName - * @param string $sValue - * @param bool $bToTop = false - * - * @return \MailSo\Mime\HeaderCollection - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - */ - public function AddByName($sName, $sValue, $bToTop = false) - { - return $this->Add(Header::NewInstance($sName, $sValue), $bToTop); - } - - /** - * @param string $sName - * @param string $sValue - * @param bool $bToTop = false - * - * @return \MailSo\Mime\HeaderCollection - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - */ - public function SetByName($sName, $sValue, $bToTop = false) - { - return $this->RemoveByName($sName)->Add(Header::NewInstance($sName, $sValue), $bToTop); - } - - /** - * @return \MailSo\Mime\Header | null - */ - public function &GetByIndex($iIndex) - { - $mResult = null; - $mResult =& parent::GetByIndex($iIndex); - return $mResult; - } - - /** - * @param string $sHeaderName - * @param bool $bCharsetAutoDetect = false - * @return string - */ - public function ValueByName($sHeaderName, $bCharsetAutoDetect = false) - { - $oHeader = null; - $oHeader =& $this->GetByName($sHeaderName); - return (null !== $oHeader) ? ($bCharsetAutoDetect ? $oHeader->ValueWithCharsetAutoDetect() : $oHeader->Value()) : ''; - } - - /** - * @param string $sHeaderName - * @param bool $bCharsetAutoDetect = false - * @return array - */ - public function ValuesByName($sHeaderName, $bCharsetAutoDetect = false) - { - $aResult = array(); - $oHeader = null; - - $sHeaderNameLower = \strtolower($sHeaderName); - $aHeaders =& $this->GetAsArray(); - foreach ($aHeaders as /* @var $oHeader \MailSo\Mime\Header */ &$oHeader) - { - if ($sHeaderNameLower === \strtolower($oHeader->Name())) - { - $aResult[] = $bCharsetAutoDetect ? $oHeader->ValueWithCharsetAutoDetect() : $oHeader->Value(); - } - } - - return $aResult; - } - - /** - * @param string $sHeaderName - * - * @return \MailSo\Mime\HeaderCollection - */ - public function RemoveByName($sHeaderName) - { - $aResult = $this->FilterList(function ($oHeader) use ($sHeaderName) { - return $oHeader && \strtolower($oHeader->Name()) !== \strtolower($sHeaderName); - }); - - return $this->SetAsArray($aResult); - } - - /** - * @param string $sHeaderName - * @param bool $bCharsetAutoDetect = false - * - * @return \MailSo\Mime\EmailCollection|null - */ - public function GetAsEmailCollection($sHeaderName, $bCharsetAutoDetect = false) - { - $oResult = null; - $sValue = $this->ValueByName($sHeaderName, $bCharsetAutoDetect); - if (0 < \strlen($sValue)) - { - $oResult = \MailSo\Mime\EmailCollection::NewInstance($sValue); - } - - return $oResult && 0 < $oResult->Count() ? $oResult : null; - } - - /** - * @param string $sHeaderName - * @return \MailSo\Mime\ParameterCollection|null - */ - public function ParametersByName($sHeaderName) - { - $oParameters = $oHeader = null; - $oHeader =& $this->GetByName($sHeaderName); - if ($oHeader) - { - $oParameters = $oHeader->Parameters(); - } - - return $oParameters; - } - - /** - * @param string $sHeaderName - * @param string $sParamName - * @return string - */ - public function ParameterValue($sHeaderName, $sParamName) - { - $oParameters = $this->ParametersByName($sHeaderName); - return (null !== $oParameters) ? $oParameters->ParameterValueByName($sParamName) : ''; - } - - /** - * @param string $sHeaderName - * @return \MailSo\Mime\Header | false - */ - public function &GetByName($sHeaderName) - { - $oResult = $oHeader = null; - - $sHeaderNameLower = \strtolower($sHeaderName); - $aHeaders =& $this->GetAsArray(); - foreach ($aHeaders as /* @var $oHeader \MailSo\Mime\Header */ &$oHeader) - { - if ($sHeaderNameLower === \strtolower($oHeader->Name())) - { - $oResult =& $oHeader; - break; - } - } - - return $oResult; - } - - /** - * @param array $aList - * @return \MailSo\Mime\HeaderCollection - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - */ - public function SetAsArray($aList) - { - parent::SetAsArray($aList); - - return $this; - } - - /** - * @param string $sParentCharset - * @return \MailSo\Mime\HeaderCollection - */ - public function SetParentCharset($sParentCharset) - { - if (0 < \strlen($sParentCharset)) - { - if ($this->sParentCharset !== $sParentCharset) - { - $oHeader = null; - $aHeaders =& $this->GetAsArray(); - - foreach ($aHeaders as /* @var $oHeader \MailSo\Mime\Header */ &$oHeader) - { - $oHeader->SetParentCharset($sParentCharset); - } - - $this->sParentCharset = $sParentCharset; - } - } - - return $this; - } - - /** - * @return void - */ - public function Clear() - { - parent::Clear(); - - $this->sRawHeaders = ''; - } - - /** - * @param string $sRawHeaders - * @param bool $bStoreRawHeaders = false - * @param string $sParentCharset = '' - * - * @return \MailSo\Mime\HeaderCollection - */ - public function Parse($sRawHeaders, $bStoreRawHeaders = false, $sParentCharset = '') - { - $this->Clear(); - - if ($bStoreRawHeaders) - { - $this->sRawHeaders = $sRawHeaders; - } - - if (0 === \strlen($this->sParentCharset)) - { - $this->sParentCharset = $sParentCharset; - } - - $aHeaders = \explode("\n", \str_replace("\r", '', $sRawHeaders)); - - $sName = null; - $sValue = null; - foreach ($aHeaders as $sHeadersValue) - { - if (0 === strlen($sHeadersValue)) - { - continue; - } - - $sFirstChar = \substr($sHeadersValue, 0, 1); - if ($sFirstChar !== ' ' && $sFirstChar !== "\t" && false === \strpos($sHeadersValue, ':')) - { - continue; - } - else if (null !== $sName && ($sFirstChar === ' ' || $sFirstChar === "\t")) - { - $sValue = \is_null($sValue) ? '' : $sValue; - - if ('?=' === \substr(\rtrim($sHeadersValue), -2)) - { - $sHeadersValue = \rtrim($sHeadersValue); - } - - if ('=?' === \substr(\ltrim($sHeadersValue), 0, 2)) - { - $sHeadersValue = \ltrim($sHeadersValue); - } - - if ('=?' === \substr($sHeadersValue, 0, 2)) - { - $sValue .= $sHeadersValue; - } - else - { - $sValue .= "\n".$sHeadersValue; - } - } - else - { - if (null !== $sName) - { - $oHeader = Header::NewInstanceFromEncodedString($sName.': '.$sValue, $this->sParentCharset); - if ($oHeader) - { - $this->Add($oHeader); - } - - $sName = null; - $sValue = null; - } - - $aHeaderParts = \explode(':', $sHeadersValue, 2); - $sName = $aHeaderParts[0]; - $sValue = isset($aHeaderParts[1]) ? $aHeaderParts[1] : ''; - - if ('?=' === \substr(\rtrim($sValue), -2)) - { - $sValue = \rtrim($sValue); - } - } - } - - if (null !== $sName) - { - $oHeader = Header::NewInstanceFromEncodedString($sName.': '.$sValue, $this->sParentCharset); - if ($oHeader) - { - $this->Add($oHeader); - } - } - - return $this; - } - - /** - * @return int - */ - public function DkimStatuses() - { - $aResult = array(); - - $aHeaders = $this->ValuesByName(\MailSo\Mime\Enumerations\Header::AUTHENTICATION_RESULTS); - if (\is_array($aHeaders) && 0 < \count($aHeaders)) - { - foreach ($aHeaders as $sHeaderValue) - { - $sStatus = ''; - $sHeader = ''; - $sDkimLine = ''; - - $aMatch = array(); - - $sHeaderValue = \preg_replace('/[\r\n\t\s]+/', ' ', $sHeaderValue); - - if (\preg_match('/dkim=.+/i', $sHeaderValue, $aMatch) && !empty($aMatch[0])) - { - $sDkimLine = $aMatch[0]; - - $aMatch = array(); - if (\preg_match('/dkim=([a-zA-Z0-9]+)/i', $sDkimLine, $aMatch) && !empty($aMatch[1])) - { - $sStatus = $aMatch[1]; - } - - $aMatch = array(); - if (\preg_match('/header\.(d|i|from)=([^\s;]+)/i', $sDkimLine, $aMatch) && !empty($aMatch[2])) - { - $sHeader = \trim($aMatch[2]); - } - - if (!empty($sStatus) && !empty($sHeader)) - { - $aResult[] = array($sStatus, $sHeader, $sDkimLine); - } - } - } - } - else - { - // X-DKIM-Authentication-Results: signer="hostinger.com" status="pass" - $aHeaders = $this->ValuesByName(\MailSo\Mime\Enumerations\Header::X_DKIM_AUTHENTICATION_RESULTS); - if (\is_array($aHeaders) && 0 < \count($aHeaders)) - { - foreach ($aHeaders as $sHeaderValue) - { - $sStatus = ''; - $sHeader = ''; - - $aMatch = array(); - - $sHeaderValue = \preg_replace('/[\r\n\t\s]+/', ' ', $sHeaderValue); - - if (\preg_match('/status[\s]?=[\s]?"([a-zA-Z0-9]+)"/i', $sHeaderValue, $aMatch) && !empty($aMatch[1])) - { - $sStatus = $aMatch[1]; - } - - if (\preg_match('/signer[\s]?=[\s]?"([^";]+)"/i', $sHeaderValue, $aMatch) && !empty($aMatch[1])) - { - $sHeader = \trim($aMatch[1]); - } - - if (!empty($sStatus) && !empty($sHeader)) - { - $aResult[] = array($sStatus, $sHeader, $sHeaderValue); - } - } - } - } - - return $aResult; - } - - /** - * @return int - */ - public function PopulateEmailColectionByDkim($oEmails) - { - if ($oEmails && $oEmails instanceof \MailSo\Mime\EmailCollection) - { - $aDkimStatuses = $this->DkimStatuses(); - if (\is_array($aDkimStatuses) && 0 < \count($aDkimStatuses)) - { - $oEmails->ForeachList(function (/* @var $oItem \MailSo\Mime\Email */ $oItem) use ($aDkimStatuses) { - if ($oItem && $oItem instanceof \MailSo\Mime\Email) - { - $sEmail = $oItem->GetEmail(); - foreach ($aDkimStatuses as $aDkimData) - { - if (isset($aDkimData[0], $aDkimData[1]) && - $aDkimData[1] === \strstr($sEmail, $aDkimData[1])) - { - $oItem->SetDkimStatusAndValue($aDkimData[0], empty($aDkimData[2]) ? '' : $aDkimData[2]); - } - } - } - }); - } - } - } - - /** - * @return string - */ - public function ToEncodedString() - { - $aResult = array(); - $aHeaders =& $this->GetAsArray(); - foreach ($aHeaders as /* @var $oHeader \MailSo\Mime\Header */ &$oHeader) - { - $aResult[] = $oHeader->EncodedValue(); - } - - return \implode(\MailSo\Mime\Enumerations\Constants::CRLF, $aResult); - } -} +sRawHeaders = ''; + $this->sParentCharset = ''; + + if (0 < \strlen($sRawHeaders)) + { + $this->Parse($sRawHeaders, $bStoreRawHeaders); + } + } + + /** + * @param string $sRawHeaders = '' + * @param bool $bStoreRawHeaders = true + * + * @return \MailSo\Mime\HeaderCollection + */ + public static function NewInstance($sRawHeaders = '', $bStoreRawHeaders = true) + { + return new self($sRawHeaders, $bStoreRawHeaders); + } + + /** + * @param string $sName + * @param string $sValue + * @param bool $bToTop = false + * + * @return \MailSo\Mime\HeaderCollection + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + */ + public function AddByName($sName, $sValue, $bToTop = false) + { + return $this->Add(Header::NewInstance($sName, $sValue), $bToTop); + } + + /** + * @param string $sName + * @param string $sValue + * @param bool $bToTop = false + * + * @return \MailSo\Mime\HeaderCollection + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + */ + public function SetByName($sName, $sValue, $bToTop = false) + { + return $this->RemoveByName($sName)->Add(Header::NewInstance($sName, $sValue), $bToTop); + } + + /** + * @return \MailSo\Mime\Header | null + */ + public function &GetByIndex($iIndex) + { + $mResult = null; + $mResult =& parent::GetByIndex($iIndex); + return $mResult; + } + + /** + * @param string $sHeaderName + * @param bool $bCharsetAutoDetect = false + * @return string + */ + public function ValueByName($sHeaderName, $bCharsetAutoDetect = false) + { + $oHeader = null; + $oHeader =& $this->GetByName($sHeaderName); + return (null !== $oHeader) ? ($bCharsetAutoDetect ? $oHeader->ValueWithCharsetAutoDetect() : $oHeader->Value()) : ''; + } + + /** + * @param string $sHeaderName + * @param bool $bCharsetAutoDetect = false + * @return array + */ + public function ValuesByName($sHeaderName, $bCharsetAutoDetect = false) + { + $aResult = array(); + $oHeader = null; + + $sHeaderNameLower = \strtolower($sHeaderName); + $aHeaders =& $this->GetAsArray(); + foreach ($aHeaders as /* @var $oHeader \MailSo\Mime\Header */ &$oHeader) + { + if ($sHeaderNameLower === \strtolower($oHeader->Name())) + { + $aResult[] = $bCharsetAutoDetect ? $oHeader->ValueWithCharsetAutoDetect() : $oHeader->Value(); + } + } + + return $aResult; + } + + /** + * @param string $sHeaderName + * + * @return \MailSo\Mime\HeaderCollection + */ + public function RemoveByName($sHeaderName) + { + $aResult = $this->FilterList(function ($oHeader) use ($sHeaderName) { + return $oHeader && \strtolower($oHeader->Name()) !== \strtolower($sHeaderName); + }); + + return $this->SetAsArray($aResult); + } + + /** + * @param string $sHeaderName + * @param bool $bCharsetAutoDetect = false + * + * @return \MailSo\Mime\EmailCollection|null + */ + public function GetAsEmailCollection($sHeaderName, $bCharsetAutoDetect = false) + { + $oResult = null; + $sValue = $this->ValueByName($sHeaderName, $bCharsetAutoDetect); + if (0 < \strlen($sValue)) + { + $oResult = \MailSo\Mime\EmailCollection::NewInstance($sValue); + } + + return $oResult && 0 < $oResult->Count() ? $oResult : null; + } + + /** + * @param string $sHeaderName + * @return \MailSo\Mime\ParameterCollection|null + */ + public function ParametersByName($sHeaderName) + { + $oParameters = $oHeader = null; + $oHeader =& $this->GetByName($sHeaderName); + if ($oHeader) + { + $oParameters = $oHeader->Parameters(); + } + + return $oParameters; + } + + /** + * @param string $sHeaderName + * @param string $sParamName + * @return string + */ + public function ParameterValue($sHeaderName, $sParamName) + { + $oParameters = $this->ParametersByName($sHeaderName); + return (null !== $oParameters) ? $oParameters->ParameterValueByName($sParamName) : ''; + } + + /** + * @param string $sHeaderName + * @return \MailSo\Mime\Header | false + */ + public function &GetByName($sHeaderName) + { + $oResult = $oHeader = null; + + $sHeaderNameLower = \strtolower($sHeaderName); + $aHeaders =& $this->GetAsArray(); + foreach ($aHeaders as /* @var $oHeader \MailSo\Mime\Header */ &$oHeader) + { + if ($sHeaderNameLower === \strtolower($oHeader->Name())) + { + $oResult =& $oHeader; + break; + } + } + + return $oResult; + } + + /** + * @param array $aList + * @return \MailSo\Mime\HeaderCollection + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + */ + public function SetAsArray($aList) + { + parent::SetAsArray($aList); + + return $this; + } + + /** + * @param string $sParentCharset + * @return \MailSo\Mime\HeaderCollection + */ + public function SetParentCharset($sParentCharset) + { + if (0 < \strlen($sParentCharset)) + { + if ($this->sParentCharset !== $sParentCharset) + { + $oHeader = null; + $aHeaders =& $this->GetAsArray(); + + foreach ($aHeaders as /* @var $oHeader \MailSo\Mime\Header */ &$oHeader) + { + $oHeader->SetParentCharset($sParentCharset); + } + + $this->sParentCharset = $sParentCharset; + } + } + + return $this; + } + + /** + * @return void + */ + public function Clear() + { + parent::Clear(); + + $this->sRawHeaders = ''; + } + + /** + * @param string $sRawHeaders + * @param bool $bStoreRawHeaders = false + * @param string $sParentCharset = '' + * + * @return \MailSo\Mime\HeaderCollection + */ + public function Parse($sRawHeaders, $bStoreRawHeaders = false, $sParentCharset = '') + { + $this->Clear(); + + if ($bStoreRawHeaders) + { + $this->sRawHeaders = $sRawHeaders; + } + + if (0 === \strlen($this->sParentCharset)) + { + $this->sParentCharset = $sParentCharset; + } + + $aHeaders = \explode("\n", \str_replace("\r", '', $sRawHeaders)); + + $sName = null; + $sValue = null; + foreach ($aHeaders as $sHeadersValue) + { + if (0 === strlen($sHeadersValue)) + { + continue; + } + + $sFirstChar = \substr($sHeadersValue, 0, 1); + if ($sFirstChar !== ' ' && $sFirstChar !== "\t" && false === \strpos($sHeadersValue, ':')) + { + continue; + } + else if (null !== $sName && ($sFirstChar === ' ' || $sFirstChar === "\t")) + { + $sValue = \is_null($sValue) ? '' : $sValue; + + if ('?=' === \substr(\rtrim($sHeadersValue), -2)) + { + $sHeadersValue = \rtrim($sHeadersValue); + } + + if ('=?' === \substr(\ltrim($sHeadersValue), 0, 2)) + { + $sHeadersValue = \ltrim($sHeadersValue); + } + + if ('=?' === \substr($sHeadersValue, 0, 2)) + { + $sValue .= $sHeadersValue; + } + else + { + $sValue .= "\n".$sHeadersValue; + } + } + else + { + if (null !== $sName) + { + $oHeader = Header::NewInstanceFromEncodedString($sName.': '.$sValue, $this->sParentCharset); + if ($oHeader) + { + $this->Add($oHeader); + } + + $sName = null; + $sValue = null; + } + + $aHeaderParts = \explode(':', $sHeadersValue, 2); + $sName = $aHeaderParts[0]; + $sValue = isset($aHeaderParts[1]) ? $aHeaderParts[1] : ''; + + if ('?=' === \substr(\rtrim($sValue), -2)) + { + $sValue = \rtrim($sValue); + } + } + } + + if (null !== $sName) + { + $oHeader = Header::NewInstanceFromEncodedString($sName.': '.$sValue, $this->sParentCharset); + if ($oHeader) + { + $this->Add($oHeader); + } + } + + return $this; + } + + /** + * @return int + */ + public function DkimStatuses() + { + $aResult = array(); + + $aHeaders = $this->ValuesByName(\MailSo\Mime\Enumerations\Header::AUTHENTICATION_RESULTS); + if (\is_array($aHeaders) && 0 < \count($aHeaders)) + { + foreach ($aHeaders as $sHeaderValue) + { + $sStatus = ''; + $sHeader = ''; + $sDkimLine = ''; + + $aMatch = array(); + + $sHeaderValue = \preg_replace('/[\r\n\t\s]+/', ' ', $sHeaderValue); + + if (\preg_match('/dkim=.+/i', $sHeaderValue, $aMatch) && !empty($aMatch[0])) + { + $sDkimLine = $aMatch[0]; + + $aMatch = array(); + if (\preg_match('/dkim=([a-zA-Z0-9]+)/i', $sDkimLine, $aMatch) && !empty($aMatch[1])) + { + $sStatus = $aMatch[1]; + } + + $aMatch = array(); + if (\preg_match('/header\.(d|i|from)=([^\s;]+)/i', $sDkimLine, $aMatch) && !empty($aMatch[2])) + { + $sHeader = \trim($aMatch[2]); + } + + if (!empty($sStatus) && !empty($sHeader)) + { + $aResult[] = array($sStatus, $sHeader, $sDkimLine); + } + } + } + } + else + { + // X-DKIM-Authentication-Results: signer="hostinger.com" status="pass" + $aHeaders = $this->ValuesByName(\MailSo\Mime\Enumerations\Header::X_DKIM_AUTHENTICATION_RESULTS); + if (\is_array($aHeaders) && 0 < \count($aHeaders)) + { + foreach ($aHeaders as $sHeaderValue) + { + $sStatus = ''; + $sHeader = ''; + + $aMatch = array(); + + $sHeaderValue = \preg_replace('/[\r\n\t\s]+/', ' ', $sHeaderValue); + + if (\preg_match('/status[\s]?=[\s]?"([a-zA-Z0-9]+)"/i', $sHeaderValue, $aMatch) && !empty($aMatch[1])) + { + $sStatus = $aMatch[1]; + } + + if (\preg_match('/signer[\s]?=[\s]?"([^";]+)"/i', $sHeaderValue, $aMatch) && !empty($aMatch[1])) + { + $sHeader = \trim($aMatch[1]); + } + + if (!empty($sStatus) && !empty($sHeader)) + { + $aResult[] = array($sStatus, $sHeader, $sHeaderValue); + } + } + } + } + + return $aResult; + } + + /** + * @return int + */ + public function PopulateEmailColectionByDkim($oEmails) + { + if ($oEmails && $oEmails instanceof \MailSo\Mime\EmailCollection) + { + $aDkimStatuses = $this->DkimStatuses(); + if (\is_array($aDkimStatuses) && 0 < \count($aDkimStatuses)) + { + $oEmails->ForeachList(function (/* @var $oItem \MailSo\Mime\Email */ $oItem) use ($aDkimStatuses) { + if ($oItem && $oItem instanceof \MailSo\Mime\Email) + { + $sEmail = $oItem->GetEmail(); + foreach ($aDkimStatuses as $aDkimData) + { + if (isset($aDkimData[0], $aDkimData[1]) && + $aDkimData[1] === \strstr($sEmail, $aDkimData[1])) + { + $oItem->SetDkimStatusAndValue($aDkimData[0], empty($aDkimData[2]) ? '' : $aDkimData[2]); + } + } + } + }); + } + } + } + + /** + * @return string + */ + public function ToEncodedString() + { + $aResult = array(); + $aHeaders =& $this->GetAsArray(); + foreach ($aHeaders as /* @var $oHeader \MailSo\Mime\Header */ &$oHeader) + { + $aResult[] = $oHeader->EncodedValue(); + } + + return \implode(\MailSo\Mime\Enumerations\Constants::CRLF, $aResult); + } +} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mime/Message.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mime/Message.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mime/Message.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mime/Message.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mime/Parameter.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mime/Parameter.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mime/Parameter.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mime/Parameter.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mime/ParameterCollection.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mime/ParameterCollection.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mime/ParameterCollection.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mime/ParameterCollection.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mime/Parser/ParserEmpty.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mime/Parser/ParserEmpty.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mime/Parser/ParserEmpty.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mime/Parser/ParserEmpty.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mime/Parser/ParserInterface.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mime/Parser/ParserInterface.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mime/Parser/ParserInterface.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mime/Parser/ParserInterface.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mime/Parser/ParserMemory.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mime/Parser/ParserMemory.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mime/Parser/ParserMemory.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mime/Parser/ParserMemory.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mime/Part.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mime/Part.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mime/Part.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mime/Part.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mime/PartCollection.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mime/PartCollection.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Mime/PartCollection.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Mime/PartCollection.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Net/Enumerations/ConnectionSecurityType.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Net/Enumerations/ConnectionSecurityType.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Net/Enumerations/ConnectionSecurityType.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Net/Enumerations/ConnectionSecurityType.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Net/Exceptions/ConnectionException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Net/Exceptions/ConnectionException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Net/Exceptions/ConnectionException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Net/Exceptions/ConnectionException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Net/Exceptions/Exception.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Net/Exceptions/Exception.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Net/Exceptions/Exception.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Net/Exceptions/Exception.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Net/Exceptions/InvalidArgumentException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Net/Exceptions/InvalidArgumentException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Net/Exceptions/InvalidArgumentException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Net/Exceptions/InvalidArgumentException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Net/Exceptions/SocketAlreadyConnectedException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Net/Exceptions/SocketAlreadyConnectedException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Net/Exceptions/SocketAlreadyConnectedException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Net/Exceptions/SocketAlreadyConnectedException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Net/Exceptions/SocketCanNotConnectToHostException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Net/Exceptions/SocketCanNotConnectToHostException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Net/Exceptions/SocketCanNotConnectToHostException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Net/Exceptions/SocketCanNotConnectToHostException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Net/Exceptions/SocketConnectionDoesNotAvailableException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Net/Exceptions/SocketConnectionDoesNotAvailableException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Net/Exceptions/SocketConnectionDoesNotAvailableException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Net/Exceptions/SocketConnectionDoesNotAvailableException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Net/Exceptions/SocketReadException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Net/Exceptions/SocketReadException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Net/Exceptions/SocketReadException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Net/Exceptions/SocketReadException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Net/Exceptions/SocketReadTimeoutException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Net/Exceptions/SocketReadTimeoutException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Net/Exceptions/SocketReadTimeoutException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Net/Exceptions/SocketReadTimeoutException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Net/Exceptions/SocketUnreadBufferException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Net/Exceptions/SocketUnreadBufferException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Net/Exceptions/SocketUnreadBufferException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Net/Exceptions/SocketUnreadBufferException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Net/Exceptions/SocketUnsuppoterdSecureConnectionException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Net/Exceptions/SocketUnsuppoterdSecureConnectionException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Net/Exceptions/SocketUnsuppoterdSecureConnectionException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Net/Exceptions/SocketUnsuppoterdSecureConnectionException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Net/Exceptions/SocketWriteException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Net/Exceptions/SocketWriteException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Net/Exceptions/SocketWriteException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Net/Exceptions/SocketWriteException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Net/NetClient.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Net/NetClient.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Net/NetClient.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Net/NetClient.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Pop3/Exceptions/Exception.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Pop3/Exceptions/Exception.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Pop3/Exceptions/Exception.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Pop3/Exceptions/Exception.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Pop3/Exceptions/LoginBadCredentialsException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Pop3/Exceptions/LoginBadCredentialsException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Pop3/Exceptions/LoginBadCredentialsException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Pop3/Exceptions/LoginBadCredentialsException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Pop3/Exceptions/NegativeResponseException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Pop3/Exceptions/NegativeResponseException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Pop3/Exceptions/NegativeResponseException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Pop3/Exceptions/NegativeResponseException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Pop3/Exceptions/ResponseException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Pop3/Exceptions/ResponseException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Pop3/Exceptions/ResponseException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Pop3/Exceptions/ResponseException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Pop3/Exceptions/RuntimeException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Pop3/Exceptions/RuntimeException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Pop3/Exceptions/RuntimeException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Pop3/Exceptions/RuntimeException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Pop3/Pop3Client.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Pop3/Pop3Client.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Pop3/Pop3Client.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Pop3/Pop3Client.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Poppassd/Exceptions/Exception.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Poppassd/Exceptions/Exception.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Poppassd/Exceptions/Exception.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Poppassd/Exceptions/Exception.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Poppassd/Exceptions/LoginBadCredentialsException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Poppassd/Exceptions/LoginBadCredentialsException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Poppassd/Exceptions/LoginBadCredentialsException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Poppassd/Exceptions/LoginBadCredentialsException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Poppassd/Exceptions/NegativeResponseException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Poppassd/Exceptions/NegativeResponseException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Poppassd/Exceptions/NegativeResponseException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Poppassd/Exceptions/NegativeResponseException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Poppassd/Exceptions/ResponseException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Poppassd/Exceptions/ResponseException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Poppassd/Exceptions/ResponseException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Poppassd/Exceptions/ResponseException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Poppassd/Exceptions/RuntimeException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Poppassd/Exceptions/RuntimeException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Poppassd/Exceptions/RuntimeException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Poppassd/Exceptions/RuntimeException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Poppassd/PoppassdClient.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Poppassd/PoppassdClient.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Poppassd/PoppassdClient.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Poppassd/PoppassdClient.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Sieve/Exceptions/Exception.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Sieve/Exceptions/Exception.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Sieve/Exceptions/Exception.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Sieve/Exceptions/Exception.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Sieve/Exceptions/LoginBadCredentialsException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Sieve/Exceptions/LoginBadCredentialsException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Sieve/Exceptions/LoginBadCredentialsException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Sieve/Exceptions/LoginBadCredentialsException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Sieve/Exceptions/LoginBadMethodException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Sieve/Exceptions/LoginBadMethodException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Sieve/Exceptions/LoginBadMethodException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Sieve/Exceptions/LoginBadMethodException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Sieve/Exceptions/LoginException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Sieve/Exceptions/LoginException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Sieve/Exceptions/LoginException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Sieve/Exceptions/LoginException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Sieve/Exceptions/NegativeResponseException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Sieve/Exceptions/NegativeResponseException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Sieve/Exceptions/NegativeResponseException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Sieve/Exceptions/NegativeResponseException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Sieve/Exceptions/ResponseException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Sieve/Exceptions/ResponseException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Sieve/Exceptions/ResponseException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Sieve/Exceptions/ResponseException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Sieve/Exceptions/RuntimeException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Sieve/Exceptions/RuntimeException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Sieve/Exceptions/RuntimeException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Sieve/Exceptions/RuntimeException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Sieve/ManageSieveClient.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Sieve/ManageSieveClient.php similarity index 95% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Sieve/ManageSieveClient.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Sieve/ManageSieveClient.php index cd4e17982ab132da670ccf27ea49eef3edf712e6..77dd400f6cb6a7dc9b8a4bbda3b9ac39aa851ade 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Sieve/ManageSieveClient.php +++ b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Sieve/ManageSieveClient.php @@ -1,653 +1,653 @@ -bIsLoggined = false; - $this->iRequestTime = 0; - $this->aCapa = array(); - $this->aModules = array(); - - $this->__USE_INITIAL_AUTH_PLAIN_COMMAND = true; - } - - /** - * @return \MailSo\Sieve\ManageSieveClient - */ - public static function NewInstance() - { - return new self(); - } - - /** - * @param string $sCapa - * - * @return bool - */ - public function IsSupported($sCapa) - { - return isset($this->aCapa[\strtoupper($sCapa)]); - } - - /** - * @param string $sModule - * - * @return bool - */ - public function IsModuleSupported($sModule) - { - return $this->IsSupported('SIEVE') && \in_array(\strtolower(\trim($sModule)), $this->aModules); - } - - /** - * @return array - */ - public function Modules() - { - return $this->aModules; - } - - /** - * @param string $sAuth - * - * @return bool - */ - public function IsAuthSupported($sAuth) - { - return $this->IsSupported('SASL') && \in_array(\strtoupper($sAuth), $this->aAuth); - } - - /** - * @param string $sServerName - * @param int $iPort - * @param int $iSecurityType = \MailSo\Net\Enumerations\ConnectionSecurityType::AUTO_DETECT - * @param bool $bVerifySsl = false - * @param bool $bAllowSelfSigned = true - * - * @return \MailSo\Sieve\ManageSieveClient - * - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Sieve\Exceptions\ResponseException - */ - public function Connect($sServerName, $iPort, - $iSecurityType = \MailSo\Net\Enumerations\ConnectionSecurityType::AUTO_DETECT, - $bVerifySsl = false, $bAllowSelfSigned = true) - { - $this->iRequestTime = \microtime(true); - - parent::Connect($sServerName, $iPort, $iSecurityType, $bVerifySsl, $bAllowSelfSigned); - - $mResponse = $this->parseResponse(); - $this->validateResponse($mResponse); - $this->parseStartupResponse($mResponse); - - if (\MailSo\Net\Enumerations\ConnectionSecurityType::UseStartTLS( - $this->IsSupported('STARTTLS'), $this->iSecurityType)) - { - $this->sendRequestWithCheck('STARTTLS'); - $this->EnableCrypto(); - - $mResponse = $this->parseResponse(); - $this->validateResponse($mResponse); - $this->parseStartupResponse($mResponse); - } - else if (\MailSo\Net\Enumerations\ConnectionSecurityType::STARTTLS === $this->iSecurityType) - { - $this->writeLogException( - new \MailSo\Net\Exceptions\SocketUnsuppoterdSecureConnectionException('STARTTLS is not supported'), - \MailSo\Log\Enumerations\Type::ERROR, true); - } - - return $this; - } - - /** - * @param string $sLogin - * @param string $sPassword - * @param string $sLoginAuthKey = '' - * - * @return \MailSo\Sieve\ManageSieveClient - * - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Sieve\Exceptions\LoginException - */ - public function Login($sLogin, $sPassword, $sLoginAuthKey = '') - { - if (!\MailSo\Base\Validator::NotEmptyString($sLogin, true) || - !\MailSo\Base\Validator::NotEmptyString($sPassword, true)) - { - $this->writeLogException( - new \MailSo\Base\Exceptions\InvalidArgumentException(), - \MailSo\Log\Enumerations\Type::ERROR, true); - } - - if ($this->IsSupported('SASL')) - { - $bAuth = false; - try - { - if ($this->IsAuthSupported('PLAIN')) - { - $sAuth = \base64_encode($sLoginAuthKey."\0".$sLogin."\0".$sPassword); - - if ($this->__USE_INITIAL_AUTH_PLAIN_COMMAND) - { - $this->sendRequest('AUTHENTICATE "PLAIN" "'.$sAuth.'"'); - } - else - { - $this->sendRequest('AUTHENTICATE "PLAIN" {'.\strlen($sAuth).'+}'); - $this->sendRequest($sAuth); - } - - $mResponse = $this->parseResponse(); - $this->validateResponse($mResponse); - $this->parseStartupResponse($mResponse); - $bAuth = true; - } - else if ($this->IsAuthSupported('LOGIN')) - { - $sLogin = \base64_encode($sLogin); - $sPassword = \base64_encode($sPassword); - - $this->sendRequest('AUTHENTICATE "LOGIN"'); - $this->sendRequest('{'.\strlen($sLogin).'+}'); - $this->sendRequest($sLogin); - $this->sendRequest('{'.\strlen($sPassword).'+}'); - $this->sendRequest($sPassword); - - $mResponse = $this->parseResponse(); - $this->validateResponse($mResponse); - $this->parseStartupResponse($mResponse); - $bAuth = true; - } - } - catch (\MailSo\Sieve\Exceptions\NegativeResponseException $oException) - { - $this->writeLogException( - new \MailSo\Sieve\Exceptions\LoginBadCredentialsException( - $oException->GetResponses(), '', 0, $oException), - \MailSo\Log\Enumerations\Type::ERROR, true); - } - - if (!$bAuth) - { - $this->writeLogException( - new \MailSo\Sieve\Exceptions\LoginBadMethodException(), - \MailSo\Log\Enumerations\Type::ERROR, true); - } - } - else - { - $this->writeLogException( - new \MailSo\Sieve\Exceptions\LoginException(), - \MailSo\Log\Enumerations\Type::ERROR, true); - } - - $this->bIsLoggined = true; - - return $this; - } - - /** - * @return \MailSo\Sieve\ManageSieveClient - * - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Sieve\Exceptions\NegativeResponseException - */ - public function Logout() - { - if ($this->bIsLoggined) - { - $this->sendRequestWithCheck('LOGOUT'); - $this->bIsLoggined = false; - } - - return $this; - } - - /** - * @return array - * - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Sieve\Exceptions\NegativeResponseException - */ - public function ListScripts() - { - $this->sendRequest('LISTSCRIPTS'); - $mResponse = $this->parseResponse(); - $this->validateResponse($mResponse); - - $aResult = array(); - if (\is_array($mResponse)) - { - foreach ($mResponse as $sLine) - { - $aTokens = $this->parseLine($sLine); - if (false === $aTokens) - { - continue; - } - - $aResult[$aTokens[0]] = 'ACTIVE' === substr($sLine, -6); - } - } - - return $aResult; - } - - /** - * @return array - * - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Sieve\Exceptions\NegativeResponseException - */ - public function Capability() - { - $this->sendRequest('CAPABILITY'); - $mResponse = $this->parseResponse(); - $this->validateResponse($mResponse); - $this->parseStartupResponse($mResponse); - - return $this->aCapa; - } - - /** - * @return \MailSo\Sieve\ManageSieveClient - * - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Sieve\Exceptions\NegativeResponseException - */ - public function Noop() - { - $this->sendRequestWithCheck('NOOP'); - - return $this; - } - - /** - * @param string $sScriptName - * - * @return string - * - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Sieve\Exceptions\NegativeResponseException - */ - public function GetScript($sScriptName) - { - $this->sendRequest('GETSCRIPT "'.$sScriptName.'"'); - $mResponse = $this->parseResponse(); - $this->validateResponse($mResponse); - - $sScript = ''; - if (\is_array($mResponse) && 0 < \count($mResponse)) - { - if ('{' === $mResponse[0]{0}) - { - \array_shift($mResponse); - } - - if (\in_array(\substr($mResponse[\count($mResponse) - 1], 0, 2), array('OK', 'NO'))) - { - \array_pop($mResponse); - } - - $sScript = \implode("\n", $mResponse); - } - - return $sScript; - } - - /** - * @param string $sScriptName - * @param string $sScriptSource - * - * @return \MailSo\Sieve\ManageSieveClient - * - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Sieve\Exceptions\NegativeResponseException - */ - public function PutScript($sScriptName, $sScriptSource) - { - $this->sendRequest('PUTSCRIPT "'.$sScriptName.'" {'.\strlen($sScriptSource).'+}'); - $this->sendRequestWithCheck($sScriptSource); - - return $this; - } - - /** - * @param string $sScriptSource - * - * @return \MailSo\Sieve\ManageSieveClient - * - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Sieve\Exceptions\NegativeResponseException - */ - public function CheckScript($sScriptSource) - { - $this->sendRequest('CHECKSCRIPT {'.\strlen($sScriptSource).'+}'); - $this->sendRequestWithCheck($sScriptSource); - - return $this; - } - - /** - * @param string $sScriptName - * - * @return \MailSo\Sieve\ManageSieveClient - * - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Sieve\Exceptions\NegativeResponseException - */ - public function SetActiveScript($sScriptName) - { - $this->sendRequestWithCheck('SETACTIVE "'.$sScriptName.'"'); - - return $this; - } - - /** - * @param string $sScriptName - * - * @return \MailSo\Sieve\ManageSieveClient - * - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Sieve\Exceptions\NegativeResponseException - */ - public function DeleteScript($sScriptName) - { - $this->sendRequestWithCheck('DELETESCRIPT "'.$sScriptName.'"'); - - return $this; - } - - /** - * @return string - * - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Sieve\Exceptions\NegativeResponseException - */ - public function GetActiveScriptName() - { - $aList = $this->ListScripts(); - if (\is_array($aList) && 0 < \count($aList)) - { - foreach ($aList as $sName => $bIsActive) - { - if ($bIsActive) - { - return $sName; - } - } - } - - return ''; - } - - /** - * @param string $sScriptName - * - * @return bool - * - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Sieve\Exceptions\NegativeResponseException - */ - public function IsActiveScript($sScriptName) - { - return $sScriptName === $this->GetActiveScriptName(); - } - - /** - * @param string $sLine - * @return array|false - */ - private function parseLine($sLine) - { - if (false === $sLine || null === $sLine || \in_array(\substr($sLine, 0, 2), array('OK', 'NO'))) - { - return false; - } - - $iStart = -1; - $iIndex = 0; - $aResult = false; - - for ($iPos = 0; $iPos < \strlen($sLine); $iPos++) - { - if ('"' === $sLine[$iPos] && '\\' !== $sLine[$iPos]) - { - if (-1 === $iStart) - { - $iStart = $iPos; - } - else - { - $aResult = \is_array($aResult) ? $aResult : array(); - $aResult[$iIndex++] = \substr($sLine, $iStart + 1, $iPos - $iStart - 1); - $iStart = -1; - } - } - } - - return \is_array($aResult) && isset($aResult[0]) ? $aResult : false; - } - - /** - * @param string $mResponse - * - * @return void - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - */ - private function parseStartupResponse($mResponse) - { - foreach ($mResponse as $sLine) - { - $aTokens = $this->parseLine($sLine); - - if (false === $aTokens || !isset($aTokens[0]) || - \in_array(\substr($sLine, 0, 2), array('OK', 'NO'))) - { - continue; - } - - $sToken = \strtoupper($aTokens[0]); - $this->aCapa[$sToken] = isset($aTokens[1]) ? $aTokens[1] : ''; - - if (isset($aTokens[1])) - { - switch ($sToken) { - case 'SASL': - $this->aAuth = \explode(' ', \strtoupper($aTokens[1])); - break; - case 'SIEVE': - $this->aModules = \explode(' ', \strtolower($aTokens[1])); - break; - } - } - } - } - - /** - * @param string $sRequest - * - * @return void - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - */ - private function sendRequest($sRequest) - { - if (!\MailSo\Base\Validator::NotEmptyString($sRequest, true)) - { - $this->writeLogException( - new \MailSo\Base\Exceptions\InvalidArgumentException(), - \MailSo\Log\Enumerations\Type::ERROR, true); - } - - $this->IsConnected(true); - - $this->sendRaw($sRequest); - } - - /** - * @param string $sRequest - * - * @return void - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Sieve\Exceptions\NegativeResponseException - */ - private function sendRequestWithCheck($sRequest) - { - $this->sendRequest($sRequest); - $this->validateResponse($this->parseResponse()); - } - - /** - * @param string $sLine - * - * @return string - */ - private function convertEndOfLine($sLine) - { - $sLine = \trim($sLine); - if ('}' === \substr($sLine, -1)) - { - $iPos = \strrpos($sLine, '{'); - if (false !== $iPos) - { - $sSunLine = \substr($sLine, $iPos + 1, -1); - if (\is_numeric($sSunLine) && 0 < (int) $sSunLine) - { - $iLen = (int) $sSunLine; - - $this->getNextBuffer($iLen, true); - - if (\strlen($this->sResponseBuffer) === $iLen) - { - $sLine = \trim(\substr_replace($sLine, $this->sResponseBuffer, $iPos)); - } - } - } - } - - return $sLine; - } - - /** - * @return array|bool - */ - private function parseResponse() - { - $this->iRequestTime = \microtime(true); - - $aResult = array(); - do - { - $this->getNextBuffer(); - - $sLine = $this->sResponseBuffer; - if (false === $sLine) - { - break; - } - else if (\in_array(\substr($sLine, 0, 2), array('OK', 'NO'))) - { - $aResult[] = $this->convertEndOfLine($sLine); - break; - } - else - { - $aResult[] = $this->convertEndOfLine($sLine); - } - } - while (true); - - $this->writeLog((\microtime(true) - $this->iRequestTime), - \MailSo\Log\Enumerations\Type::TIME); - - return $aResult; - } - - /** - * @throws \MailSo\Sieve\Exceptions\NegativeResponseException - */ - private function validateResponse($aResponse) - { - if (!\is_array($aResponse) || 0 === \count($aResponse) || - 'OK' !== \substr($aResponse[\count($aResponse) - 1], 0, 2)) - { - $this->writeLogException( - new \MailSo\Sieve\Exceptions\NegativeResponseException($aResponse), - \MailSo\Log\Enumerations\Type::WARNING, true); - } - } - - /** - * @return string - */ - protected function getLogName() - { - return 'SIEVE'; - } - - /** - * @param \MailSo\Log\Logger $oLogger - * - * @return \MailSo\Sieve\ManageSieveClient - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - */ - public function SetLogger($oLogger) - { - parent::SetLogger($oLogger); - - return $this; - } -} +bIsLoggined = false; + $this->iRequestTime = 0; + $this->aCapa = array(); + $this->aModules = array(); + + $this->__USE_INITIAL_AUTH_PLAIN_COMMAND = true; + } + + /** + * @return \MailSo\Sieve\ManageSieveClient + */ + public static function NewInstance() + { + return new self(); + } + + /** + * @param string $sCapa + * + * @return bool + */ + public function IsSupported($sCapa) + { + return isset($this->aCapa[\strtoupper($sCapa)]); + } + + /** + * @param string $sModule + * + * @return bool + */ + public function IsModuleSupported($sModule) + { + return $this->IsSupported('SIEVE') && \in_array(\strtolower(\trim($sModule)), $this->aModules); + } + + /** + * @return array + */ + public function Modules() + { + return $this->aModules; + } + + /** + * @param string $sAuth + * + * @return bool + */ + public function IsAuthSupported($sAuth) + { + return $this->IsSupported('SASL') && \in_array(\strtoupper($sAuth), $this->aAuth); + } + + /** + * @param string $sServerName + * @param int $iPort + * @param int $iSecurityType = \MailSo\Net\Enumerations\ConnectionSecurityType::AUTO_DETECT + * @param bool $bVerifySsl = false + * @param bool $bAllowSelfSigned = true + * + * @return \MailSo\Sieve\ManageSieveClient + * + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Sieve\Exceptions\ResponseException + */ + public function Connect($sServerName, $iPort, + $iSecurityType = \MailSo\Net\Enumerations\ConnectionSecurityType::AUTO_DETECT, + $bVerifySsl = false, $bAllowSelfSigned = true) + { + $this->iRequestTime = \microtime(true); + + parent::Connect($sServerName, $iPort, $iSecurityType, $bVerifySsl, $bAllowSelfSigned); + + $mResponse = $this->parseResponse(); + $this->validateResponse($mResponse); + $this->parseStartupResponse($mResponse); + + if (\MailSo\Net\Enumerations\ConnectionSecurityType::UseStartTLS( + $this->IsSupported('STARTTLS'), $this->iSecurityType)) + { + $this->sendRequestWithCheck('STARTTLS'); + $this->EnableCrypto(); + + $mResponse = $this->parseResponse(); + $this->validateResponse($mResponse); + $this->parseStartupResponse($mResponse); + } + else if (\MailSo\Net\Enumerations\ConnectionSecurityType::STARTTLS === $this->iSecurityType) + { + $this->writeLogException( + new \MailSo\Net\Exceptions\SocketUnsuppoterdSecureConnectionException('STARTTLS is not supported'), + \MailSo\Log\Enumerations\Type::ERROR, true); + } + + return $this; + } + + /** + * @param string $sLogin + * @param string $sPassword + * @param string $sLoginAuthKey = '' + * + * @return \MailSo\Sieve\ManageSieveClient + * + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Sieve\Exceptions\LoginException + */ + public function Login($sLogin, $sPassword, $sLoginAuthKey = '') + { + if (!\MailSo\Base\Validator::NotEmptyString($sLogin, true) || + !\MailSo\Base\Validator::NotEmptyString($sPassword, true)) + { + $this->writeLogException( + new \MailSo\Base\Exceptions\InvalidArgumentException(), + \MailSo\Log\Enumerations\Type::ERROR, true); + } + + if ($this->IsSupported('SASL')) + { + $bAuth = false; + try + { + if ($this->IsAuthSupported('PLAIN')) + { + $sAuth = \base64_encode($sLoginAuthKey."\0".$sLogin."\0".$sPassword); + + if ($this->__USE_INITIAL_AUTH_PLAIN_COMMAND) + { + $this->sendRequest('AUTHENTICATE "PLAIN" "'.$sAuth.'"'); + } + else + { + $this->sendRequest('AUTHENTICATE "PLAIN" {'.\strlen($sAuth).'+}'); + $this->sendRequest($sAuth); + } + + $mResponse = $this->parseResponse(); + $this->validateResponse($mResponse); + $this->parseStartupResponse($mResponse); + $bAuth = true; + } + else if ($this->IsAuthSupported('LOGIN')) + { + $sLogin = \base64_encode($sLogin); + $sPassword = \base64_encode($sPassword); + + $this->sendRequest('AUTHENTICATE "LOGIN"'); + $this->sendRequest('{'.\strlen($sLogin).'+}'); + $this->sendRequest($sLogin); + $this->sendRequest('{'.\strlen($sPassword).'+}'); + $this->sendRequest($sPassword); + + $mResponse = $this->parseResponse(); + $this->validateResponse($mResponse); + $this->parseStartupResponse($mResponse); + $bAuth = true; + } + } + catch (\MailSo\Sieve\Exceptions\NegativeResponseException $oException) + { + $this->writeLogException( + new \MailSo\Sieve\Exceptions\LoginBadCredentialsException( + $oException->GetResponses(), '', 0, $oException), + \MailSo\Log\Enumerations\Type::ERROR, true); + } + + if (!$bAuth) + { + $this->writeLogException( + new \MailSo\Sieve\Exceptions\LoginBadMethodException(), + \MailSo\Log\Enumerations\Type::ERROR, true); + } + } + else + { + $this->writeLogException( + new \MailSo\Sieve\Exceptions\LoginException(), + \MailSo\Log\Enumerations\Type::ERROR, true); + } + + $this->bIsLoggined = true; + + return $this; + } + + /** + * @return \MailSo\Sieve\ManageSieveClient + * + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Sieve\Exceptions\NegativeResponseException + */ + public function Logout() + { + if ($this->bIsLoggined) + { + $this->sendRequestWithCheck('LOGOUT'); + $this->bIsLoggined = false; + } + + return $this; + } + + /** + * @return array + * + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Sieve\Exceptions\NegativeResponseException + */ + public function ListScripts() + { + $this->sendRequest('LISTSCRIPTS'); + $mResponse = $this->parseResponse(); + $this->validateResponse($mResponse); + + $aResult = array(); + if (\is_array($mResponse)) + { + foreach ($mResponse as $sLine) + { + $aTokens = $this->parseLine($sLine); + if (false === $aTokens) + { + continue; + } + + $aResult[$aTokens[0]] = 'ACTIVE' === substr($sLine, -6); + } + } + + return $aResult; + } + + /** + * @return array + * + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Sieve\Exceptions\NegativeResponseException + */ + public function Capability() + { + $this->sendRequest('CAPABILITY'); + $mResponse = $this->parseResponse(); + $this->validateResponse($mResponse); + $this->parseStartupResponse($mResponse); + + return $this->aCapa; + } + + /** + * @return \MailSo\Sieve\ManageSieveClient + * + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Sieve\Exceptions\NegativeResponseException + */ + public function Noop() + { + $this->sendRequestWithCheck('NOOP'); + + return $this; + } + + /** + * @param string $sScriptName + * + * @return string + * + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Sieve\Exceptions\NegativeResponseException + */ + public function GetScript($sScriptName) + { + $this->sendRequest('GETSCRIPT "'.$sScriptName.'"'); + $mResponse = $this->parseResponse(); + $this->validateResponse($mResponse); + + $sScript = ''; + if (\is_array($mResponse) && 0 < \count($mResponse)) + { + if ('{' === $mResponse[0]{0}) + { + \array_shift($mResponse); + } + + if (\in_array(\substr($mResponse[\count($mResponse) - 1], 0, 2), array('OK', 'NO'))) + { + \array_pop($mResponse); + } + + $sScript = \implode("\n", $mResponse); + } + + return $sScript; + } + + /** + * @param string $sScriptName + * @param string $sScriptSource + * + * @return \MailSo\Sieve\ManageSieveClient + * + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Sieve\Exceptions\NegativeResponseException + */ + public function PutScript($sScriptName, $sScriptSource) + { + $this->sendRequest('PUTSCRIPT "'.$sScriptName.'" {'.\strlen($sScriptSource).'+}'); + $this->sendRequestWithCheck($sScriptSource); + + return $this; + } + + /** + * @param string $sScriptSource + * + * @return \MailSo\Sieve\ManageSieveClient + * + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Sieve\Exceptions\NegativeResponseException + */ + public function CheckScript($sScriptSource) + { + $this->sendRequest('CHECKSCRIPT {'.\strlen($sScriptSource).'+}'); + $this->sendRequestWithCheck($sScriptSource); + + return $this; + } + + /** + * @param string $sScriptName + * + * @return \MailSo\Sieve\ManageSieveClient + * + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Sieve\Exceptions\NegativeResponseException + */ + public function SetActiveScript($sScriptName) + { + $this->sendRequestWithCheck('SETACTIVE "'.$sScriptName.'"'); + + return $this; + } + + /** + * @param string $sScriptName + * + * @return \MailSo\Sieve\ManageSieveClient + * + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Sieve\Exceptions\NegativeResponseException + */ + public function DeleteScript($sScriptName) + { + $this->sendRequestWithCheck('DELETESCRIPT "'.$sScriptName.'"'); + + return $this; + } + + /** + * @return string + * + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Sieve\Exceptions\NegativeResponseException + */ + public function GetActiveScriptName() + { + $aList = $this->ListScripts(); + if (\is_array($aList) && 0 < \count($aList)) + { + foreach ($aList as $sName => $bIsActive) + { + if ($bIsActive) + { + return $sName; + } + } + } + + return ''; + } + + /** + * @param string $sScriptName + * + * @return bool + * + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Sieve\Exceptions\NegativeResponseException + */ + public function IsActiveScript($sScriptName) + { + return $sScriptName === $this->GetActiveScriptName(); + } + + /** + * @param string $sLine + * @return array|false + */ + private function parseLine($sLine) + { + if (false === $sLine || null === $sLine || \in_array(\substr($sLine, 0, 2), array('OK', 'NO'))) + { + return false; + } + + $iStart = -1; + $iIndex = 0; + $aResult = false; + + for ($iPos = 0; $iPos < \strlen($sLine); $iPos++) + { + if ('"' === $sLine[$iPos] && '\\' !== $sLine[$iPos]) + { + if (-1 === $iStart) + { + $iStart = $iPos; + } + else + { + $aResult = \is_array($aResult) ? $aResult : array(); + $aResult[$iIndex++] = \substr($sLine, $iStart + 1, $iPos - $iStart - 1); + $iStart = -1; + } + } + } + + return \is_array($aResult) && isset($aResult[0]) ? $aResult : false; + } + + /** + * @param string $mResponse + * + * @return void + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + */ + private function parseStartupResponse($mResponse) + { + foreach ($mResponse as $sLine) + { + $aTokens = $this->parseLine($sLine); + + if (false === $aTokens || !isset($aTokens[0]) || + \in_array(\substr($sLine, 0, 2), array('OK', 'NO'))) + { + continue; + } + + $sToken = \strtoupper($aTokens[0]); + $this->aCapa[$sToken] = isset($aTokens[1]) ? $aTokens[1] : ''; + + if (isset($aTokens[1])) + { + switch ($sToken) { + case 'SASL': + $this->aAuth = \explode(' ', \strtoupper($aTokens[1])); + break; + case 'SIEVE': + $this->aModules = \explode(' ', \strtolower($aTokens[1])); + break; + } + } + } + } + + /** + * @param string $sRequest + * + * @return void + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + */ + private function sendRequest($sRequest) + { + if (!\MailSo\Base\Validator::NotEmptyString($sRequest, true)) + { + $this->writeLogException( + new \MailSo\Base\Exceptions\InvalidArgumentException(), + \MailSo\Log\Enumerations\Type::ERROR, true); + } + + $this->IsConnected(true); + + $this->sendRaw($sRequest); + } + + /** + * @param string $sRequest + * + * @return void + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Sieve\Exceptions\NegativeResponseException + */ + private function sendRequestWithCheck($sRequest) + { + $this->sendRequest($sRequest); + $this->validateResponse($this->parseResponse()); + } + + /** + * @param string $sLine + * + * @return string + */ + private function convertEndOfLine($sLine) + { + $sLine = \trim($sLine); + if ('}' === \substr($sLine, -1)) + { + $iPos = \strrpos($sLine, '{'); + if (false !== $iPos) + { + $sSunLine = \substr($sLine, $iPos + 1, -1); + if (\is_numeric($sSunLine) && 0 < (int) $sSunLine) + { + $iLen = (int) $sSunLine; + + $this->getNextBuffer($iLen, true); + + if (\strlen($this->sResponseBuffer) === $iLen) + { + $sLine = \trim(\substr_replace($sLine, $this->sResponseBuffer, $iPos)); + } + } + } + } + + return $sLine; + } + + /** + * @return array|bool + */ + private function parseResponse() + { + $this->iRequestTime = \microtime(true); + + $aResult = array(); + do + { + $this->getNextBuffer(); + + $sLine = $this->sResponseBuffer; + if (false === $sLine) + { + break; + } + else if (\in_array(\substr($sLine, 0, 2), array('OK', 'NO'))) + { + $aResult[] = $this->convertEndOfLine($sLine); + break; + } + else + { + $aResult[] = $this->convertEndOfLine($sLine); + } + } + while (true); + + $this->writeLog((\microtime(true) - $this->iRequestTime), + \MailSo\Log\Enumerations\Type::TIME); + + return $aResult; + } + + /** + * @throws \MailSo\Sieve\Exceptions\NegativeResponseException + */ + private function validateResponse($aResponse) + { + if (!\is_array($aResponse) || 0 === \count($aResponse) || + 'OK' !== \substr($aResponse[\count($aResponse) - 1], 0, 2)) + { + $this->writeLogException( + new \MailSo\Sieve\Exceptions\NegativeResponseException($aResponse), + \MailSo\Log\Enumerations\Type::WARNING, true); + } + } + + /** + * @return string + */ + protected function getLogName() + { + return 'SIEVE'; + } + + /** + * @param \MailSo\Log\Logger $oLogger + * + * @return \MailSo\Sieve\ManageSieveClient + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + */ + public function SetLogger($oLogger) + { + parent::SetLogger($oLogger); + + return $this; + } +} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Smtp/Exceptions/Exception.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Smtp/Exceptions/Exception.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Smtp/Exceptions/Exception.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Smtp/Exceptions/Exception.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Smtp/Exceptions/LoginBadCredentialsException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Smtp/Exceptions/LoginBadCredentialsException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Smtp/Exceptions/LoginBadCredentialsException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Smtp/Exceptions/LoginBadCredentialsException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Smtp/Exceptions/LoginBadMethodException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Smtp/Exceptions/LoginBadMethodException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Smtp/Exceptions/LoginBadMethodException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Smtp/Exceptions/LoginBadMethodException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Smtp/Exceptions/LoginException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Smtp/Exceptions/LoginException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Smtp/Exceptions/LoginException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Smtp/Exceptions/LoginException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Smtp/Exceptions/NegativeResponseException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Smtp/Exceptions/NegativeResponseException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Smtp/Exceptions/NegativeResponseException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Smtp/Exceptions/NegativeResponseException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Smtp/Exceptions/ResponseException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Smtp/Exceptions/ResponseException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Smtp/Exceptions/ResponseException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Smtp/Exceptions/ResponseException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Smtp/Exceptions/RuntimeException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Smtp/Exceptions/RuntimeException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Smtp/Exceptions/RuntimeException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Smtp/Exceptions/RuntimeException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Smtp/SmtpClient.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Smtp/SmtpClient.php similarity index 95% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Smtp/SmtpClient.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Smtp/SmtpClient.php index f536b72ae549e4b8f760f9bc30926f5cc2c56434..ce09f029aabde5d4a173ea0916d6dc33be44fbec 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Smtp/SmtpClient.php +++ b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Smtp/SmtpClient.php @@ -1,838 +1,838 @@ -aAuthTypes = array(); - - $this->iRequestTime = 0; - $this->iSizeCapaValue = 0; - $this->aResults = array(); - $this->aCapa = array(); - - $this->bHelo = false; - $this->bRcpt = false; - $this->bMail = false; - $this->bData = false; - } - - /** - * @return \MailSo\Smtp\SmtpClient - */ - public static function NewInstance() - { - return new self(); - } - - /** - * @return bool - */ - public function IsSupported($sCapa) - { - return in_array(strtoupper($sCapa), $this->aCapa); - } - - /** - * @return bool - */ - public function IsAuthSupported($sAuth) - { - return in_array(strtoupper($sAuth), $this->aAuthTypes); - } - - /** - * @return bool - */ - public function HasSupportedAuth() - { - return $this->IsAuthSupported('PLAIN') || $this->IsAuthSupported('LOGIN'); - } - - /** - * @return string - */ - public static function EhloHelper() - { - $sEhloHost = empty($_SERVER['SERVER_NAME']) ? '' : \trim($_SERVER['SERVER_NAME']); - if (empty($sEhloHost)) - { - $sEhloHost = empty($_SERVER['HTTP_HOST']) ? '' : \trim($_SERVER['HTTP_HOST']); - } - - if (empty($sEhloHost)) - { - $sEhloHost = \function_exists('gethostname') ? \gethostname() : 'localhost'; - } - - $sEhloHost = \trim(\preg_replace('/:\d+$/', '', \trim($sEhloHost))); - - if (\preg_match('/^\d+\.\d+\.\d+\.\d+$/', $sEhloHost)) - { - $sEhloHost = '['.$sEhloHost.']'; - } - - return empty($sEhloHost) ? 'localhost' : $sEhloHost; - } - - /** - * @param string $sServerName - * @param int $iPort = 25 - * @param string $sEhloHost = '[127.0.0.1]' - * @param int $iSecurityType = \MailSo\Net\Enumerations\ConnectionSecurityType::AUTO_DETECT - * @param bool $bVerifySsl = false - * @param bool $bAllowSelfSigned = true - * - * @return \MailSo\Smtp\SmtpClient - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Smtp\Exceptions\ResponseException - */ - public function Connect($sServerName, $iPort = 25, $sEhloHost = '[127.0.0.1]', - $iSecurityType = \MailSo\Net\Enumerations\ConnectionSecurityType::AUTO_DETECT, - $bVerifySsl = false, $bAllowSelfSigned = true) - { - $this->iRequestTime = microtime(true); - - parent::Connect($sServerName, $iPort, $iSecurityType, $bVerifySsl, $bAllowSelfSigned); - - $this->validateResponse(220); - - $this->preLoginStartTLSAndEhloProcess($sEhloHost); - - return $this; - } - - /** - * @param string $sLogin - * @param string $sPassword - * @param boolean $bUseAuthPlainIfSupported = true - * @param boolean $bUseAuthCramMd5IfSupported = true - * - * @return \MailSo\Smtp\SmtpClient - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Smtp\Exceptions\Exception - */ - public function Login($sLogin, $sPassword, $bUseAuthPlainIfSupported = true, $bUseAuthCramMd5IfSupported = true) - { - $sLogin = \MailSo\Base\Utils::IdnToAscii(\MailSo\Base\Utils::Trim($sLogin)); - - if ($bUseAuthCramMd5IfSupported && $this->IsAuthSupported('CRAM-MD5')) - { - try - { - $this->sendRequestWithCheck('AUTH', 334, 'CRAM-MD5'); - } - catch (\MailSo\Smtp\Exceptions\NegativeResponseException $oException) - { - $this->writeLogException( - new \MailSo\Smtp\Exceptions\LoginBadMethodException( - $oException->GetResponses(), $oException->getMessage(), 0, $oException), - \MailSo\Log\Enumerations\Type::NOTICE, true); - } - - $sTicket = ''; - - $sContinuationResponse = !empty($this->aResults[0]) ? \trim($this->aResults[0]) : ''; - if ($sContinuationResponse && '334 ' === \substr($sContinuationResponse, 0, 4) && 0 < \strlen(\substr($sContinuationResponse, 4))) - { - $sTicket = @\base64_decode(\substr($sContinuationResponse, 4)); - $this->writeLogWithCrlf('ticket: '.$sTicket); - } - - if (empty($sTicket)) - { - $this->writeLogException( - new \MailSo\Smtp\Exceptions\NegativeResponseException(), - \MailSo\Log\Enumerations\Type::NOTICE, true - ); - } - - try - { - $this->sendRequestWithCheck(\base64_encode($sLogin.' '.\MailSo\Base\Utils::Hmac($sTicket, $sPassword)), 235, '', true); - } - catch (\MailSo\Smtp\Exceptions\NegativeResponseException $oException) - { - $this->writeLogException( - new \MailSo\Smtp\Exceptions\LoginBadCredentialsException( - $oException->GetResponses(), $oException->getMessage(), 0, $oException), - \MailSo\Log\Enumerations\Type::NOTICE, true); - } - } - else if ($bUseAuthPlainIfSupported && $this->IsAuthSupported('PLAIN')) - { - if ($this->__USE_SINGLE_LINE_AUTH_PLAIN_COMMAND) - { - try - { - $this->sendRequestWithCheck('AUTH', 235, 'PLAIN '.\base64_encode("\0".$sLogin."\0".$sPassword), true); - } - catch (\MailSo\Smtp\Exceptions\NegativeResponseException $oException) - { - $this->writeLogException( - new \MailSo\Smtp\Exceptions\LoginBadCredentialsException( - $oException->GetResponses(), $oException->getMessage(), 0, $oException), - \MailSo\Log\Enumerations\Type::NOTICE, true); - } - } - else - { - try - { - $this->sendRequestWithCheck('AUTH', 334, 'PLAIN'); - } - catch (\MailSo\Smtp\Exceptions\NegativeResponseException $oException) - { - $this->writeLogException( - new \MailSo\Smtp\Exceptions\LoginBadMethodException( - $oException->GetResponses(), $oException->getMessage(), 0, $oException), - \MailSo\Log\Enumerations\Type::NOTICE, true); - } - - try - { - $this->sendRequestWithCheck(\base64_encode("\0".$sLogin."\0".$sPassword), 235, '', true); - } - catch (\MailSo\Smtp\Exceptions\NegativeResponseException $oException) - { - $this->writeLogException( - new \MailSo\Smtp\Exceptions\LoginBadCredentialsException( - $oException->GetResponses(), $oException->getMessage(), 0, $oException), - \MailSo\Log\Enumerations\Type::NOTICE, true); - } - } - } - else if ($this->IsAuthSupported('LOGIN')) - { - try - { - $this->sendRequestWithCheck('AUTH', 334, 'LOGIN'); - } - catch (\MailSo\Smtp\Exceptions\NegativeResponseException $oException) - { - $this->writeLogException( - new \MailSo\Smtp\Exceptions\LoginBadMethodException( - $oException->GetResponses(), $oException->getMessage(), 0, $oException), - \MailSo\Log\Enumerations\Type::NOTICE, true); - } - - try - { - $this->sendRequestWithCheck(\base64_encode($sLogin), 334, ''); - $this->sendRequestWithCheck(\base64_encode($sPassword), 235, '', true); - } - catch (\MailSo\Smtp\Exceptions\NegativeResponseException $oException) - { - $this->writeLogException( - new \MailSo\Smtp\Exceptions\LoginBadCredentialsException( - $oException->GetResponses(), $oException->getMessage(), 0, $oException), - \MailSo\Log\Enumerations\Type::NOTICE, true); - } - } - else - { - $this->writeLogException( - new \MailSo\Smtp\Exceptions\LoginBadMethodException(), - \MailSo\Log\Enumerations\Type::NOTICE, true); - } - - return $this; - } - - /** - * @param string $sXOAuth2Token - * - * @return \MailSo\Smtp\SmtpClient - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Smtp\Exceptions\Exception - */ - public function LoginWithXOauth2($sXOAuth2Token) - { - if ($this->IsAuthSupported('XOAUTH2')) - { - try - { - $this->sendRequestWithCheck('AUTH', 235, 'XOAUTH2 '.\trim($sXOAuth2Token)); - } - catch (\MailSo\Smtp\Exceptions\NegativeResponseException $oException) - { - $this->writeLogException( - new \MailSo\Smtp\Exceptions\LoginBadCredentialsException( - $oException->GetResponses(), $oException->getMessage(), 0, $oException), - \MailSo\Log\Enumerations\Type::NOTICE, true); - } - } - else - { - $this->writeLogException( - new \MailSo\Smtp\Exceptions\LoginBadMethodException(), - \MailSo\Log\Enumerations\Type::NOTICE, true); - } - - return $this; - } - - /** - * @param string $sFrom - * @param string $sSizeIfSupported = '' - * @param bool $bDsn = false - * - * @return \MailSo\Smtp\SmtpClient - * - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Smtp\Exceptions\Exception - */ - public function MailFrom($sFrom, $sSizeIfSupported = '', $bDsn = false) - { - $sFrom = \MailSo\Base\Utils::IdnToAscii( - \MailSo\Base\Utils::Trim($sFrom), true); - - $sCmd = 'FROM:<'.$sFrom.'>'; - - $sSizeIfSupported = (string) $sSizeIfSupported; - if (0 < \strlen($sSizeIfSupported) && \is_numeric($sSizeIfSupported) && $this->IsSupported('SIZE')) - { - $sCmd .= ' SIZE='.$sSizeIfSupported; - } - - if ($bDsn && $this->IsSupported('DSN')) - { - $sCmd .= ' RET=HDRS'; - } - - $this->sendRequestWithCheck('MAIL', 250, $sCmd); - - $this->bMail = true; - $this->bRcpt = false; - $this->bData = false; - - return $this; - } - - /** - * @param string $sTo - * @param bool $bDsn = false - * - * @return \MailSo\Smtp\SmtpClient - * - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Smtp\Exceptions\Exception - */ - public function Rcpt($sTo, $bDsn = false) - { - if (!$this->bMail) - { - $this->writeLogException( - new Exceptions\RuntimeException('No sender reverse path has been supplied'), - \MailSo\Log\Enumerations\Type::ERROR, true); - } - - $sTo = \MailSo\Base\Utils::IdnToAscii( - \MailSo\Base\Utils::Trim($sTo), true); - - $sCmd = 'TO:<'.$sTo.'>'; - - if ($bDsn && $this->IsSupported('DSN')) - { - $sCmd .= ' NOTIFY=SUCCESS,FAILURE'; - } - - $this->sendRequestWithCheck( - 'RCPT', array(250, 251), $sCmd, false, - 'Failed to add recipient "'.$sTo.'"' - ); - - $this->bRcpt = true; - - return $this; - } - - /** - * @param string $sTo - * - * @return \MailSo\Smtp\SmtpClient - * - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Smtp\Exceptions\Exception - */ - public function MailTo($sTo) - { - return $this->Rcpt($sTo); - } - - /** - * @param string $sData - * - * @return \MailSo\Smtp\SmtpClient - * - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Smtp\Exceptions\Exception - */ - public function Data($sData) - { - if (!\MailSo\Base\Validator::NotEmptyString($sData, true)) - { - throw new \MailSo\Base\Exceptions\InvalidArgumentException(); - } - - $rDataStream = \MailSo\Base\ResourceRegistry::CreateMemoryResourceFromString($sData); - unset($sData); - $this->DataWithStream($rDataStream); - \MailSo\Base\ResourceRegistry::CloseMemoryResource($rDataStream); - - return $this; - } - - /** - * @param resource $rDataStream - * - * @return \MailSo\Smtp\SmtpClient - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Smtp\Exceptions\Exception - */ - public function DataWithStream($rDataStream) - { - if (!\is_resource($rDataStream)) - { - throw new \MailSo\Base\Exceptions\InvalidArgumentException(); - } - - if (!$this->bRcpt) - { - $this->writeLogException( - new Exceptions\RuntimeException('No recipient forward path has been supplied'), - \MailSo\Log\Enumerations\Type::ERROR, true); - } - - $this->sendRequestWithCheck('DATA', 354); - - $this->writeLog('Message data.', \MailSo\Log\Enumerations\Type::NOTE); - - $this->bRunningCallback = true; - - while (!\feof($rDataStream)) - { - $sBuffer = \fgets($rDataStream); - if (false !== $sBuffer) - { - if (0 === \strpos($sBuffer, '.')) - { - $sBuffer = '.'.$sBuffer; - } - - $this->sendRaw(\rtrim($sBuffer, "\r\n"), false); - - \MailSo\Base\Utils::ResetTimeLimit(); - continue; - } - else if (!\feof($rDataStream)) - { - $this->writeLogException( - new Exceptions\RuntimeException('Cannot read input resource'), - \MailSo\Log\Enumerations\Type::ERROR, true); - } - - break; - } - - $this->sendRequestWithCheck('.', 250); - - $this->bRunningCallback = false; - - $this->bData = true; - - return $this; - } - - /** - * @return \MailSo\Smtp\SmtpClient - * - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Smtp\Exceptions\Exception - */ - public function Rset() - { - $this->sendRequestWithCheck('RSET', array(250, 220)); - - $this->bMail = false; - $this->bRcpt = false; - $this->bData = false; - - return $this; - } - - /** - * @return \MailSo\Smtp\SmtpClient - * - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Smtp\Exceptions\Exception - */ - public function Vrfy($sUser) - { - $sUser = \MailSo\Base\Utils::IdnToAscii( - \MailSo\Base\Utils::Trim($sUser)); - - $this->sendRequestWithCheck('VRFY', array(250, 251, 252), $sUser); - - return $this; - } - - /** - * @return \MailSo\Smtp\SmtpClient - * - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Smtp\Exceptions\Exception - */ - public function Noop() - { - $this->sendRequestWithCheck('NOOP', 250); - - return $this; - } - - /** - * @return \MailSo\Smtp\SmtpClient - * - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Smtp\Exceptions\Exception - */ - public function Logout() - { - if ($this->IsConnected()) - { - $this->sendRequestWithCheck('QUIT', 221); - } - - $this->bHelo = false; - $this->bMail = false; - $this->bRcpt = false; - $this->bData = false; - - return $this; - } - - /** - * @param string $sEhloHost - * - * @return void - */ - private function preLoginStartTLSAndEhloProcess($sEhloHost) - { - if ($this->bHelo) - { - $this->writeLogException( - new Exceptions\RuntimeException('Cannot issue EHLO/HELO to existing session'), - \MailSo\Log\Enumerations\Type::ERROR, true); - } - - $this->ehloOrHelo($sEhloHost); - - if (\MailSo\Net\Enumerations\ConnectionSecurityType::UseStartTLS( - $this->IsSupported('STARTTLS'), $this->iSecurityType, $this->HasSupportedAuth())) - { - $this->sendRequestWithCheck('STARTTLS', 220); - $this->EnableCrypto(); - - $this->ehloOrHelo($sEhloHost); - } - else if (\MailSo\Net\Enumerations\ConnectionSecurityType::STARTTLS === $this->iSecurityType) - { - $this->writeLogException( - new \MailSo\Net\Exceptions\SocketUnsuppoterdSecureConnectionException('STARTTLS is not supported'), - \MailSo\Log\Enumerations\Type::ERROR, true); - } - - $this->bHelo = true; - } - - /** - * @param string $sCommand - * @param string $sAddToCommand = '' - * @param bool $bSecureLog = false - * - * @return void - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - */ - private function sendRequest($sCommand, $sAddToCommand = '', $bSecureLog = false) - { - if (!\MailSo\Base\Validator::NotEmptyString($sCommand, true)) - { - $this->writeLogException( - new \MailSo\Base\Exceptions\InvalidArgumentException(), - \MailSo\Log\Enumerations\Type::ERROR, true); - } - - $this->IsConnected(true); - - $sCommand = \trim($sCommand); - $sRealCommand = $sCommand.(0 === \strlen($sAddToCommand) ? '' : ' '.$sAddToCommand); - - $sFakeCommand = ($bSecureLog) ? '********' : ''; - - $this->iRequestTime = \microtime(true); - $this->sendRaw($sRealCommand, true, $sFakeCommand); - - return $this; - } - - /** - * @param string $sCommand - * @param int|array $mExpectCode - * @param string $sAddToCommand = '' - * @param bool $bSecureLog = false - * @param string $sErrorPrefix = '' - * - * @return void - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Smtp\Exceptions\Exception - */ - private function sendRequestWithCheck($sCommand, $mExpectCode, $sAddToCommand = '', $bSecureLog = false, $sErrorPrefix = '') - { - $this->sendRequest($sCommand, $sAddToCommand, $bSecureLog); - $this->validateResponse($mExpectCode, $sErrorPrefix); - } - - /** - * @param string $sHost - * - * @return void - */ - private function ehloOrHelo($sHost) - { - try - { - $this->ehlo($sHost); - } - catch (\Exception $oException) - { - try - { - $this->helo($sHost); - } - catch (\Exception $oException) - { - throw $oException; - } - } - - return $this; - } - - /** - * @param string $sHost - * - * @return void - * - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Smtp\Exceptions\Exception - */ - private function ehlo($sHost) - { - $this->sendRequestWithCheck('EHLO', 250, $sHost); - - foreach ($this->aResults as $sLine) - { - $aMatch = array(); - if (\preg_match('/[\d]+[ \-](.+)$/', $sLine, $aMatch) && isset($aMatch[1]) && 0 < \strlen($aMatch[1])) - { - $sLine = \trim($aMatch[1]); - $aLine = \preg_split('/[ =]/', $sLine, 2); - if (\is_array($aLine) && 0 < \count($aLine) && !empty($aLine[0])) - { - $sCapa = \strtoupper($aLine[0]); - if (('AUTH' === $sCapa || 'SIZE' === $sCapa) && !empty($aLine[1])) - { - $sSubLine = \trim(\strtoupper($aLine[1])); - if (0 < \strlen($sSubLine)) - { - if ('AUTH' === $sCapa) - { - $this->aAuthTypes = \explode(' ', $sSubLine); - } - else if ('SIZE' === $sCapa && \is_numeric($sSubLine)) - { - $this->iSizeCapaValue = (int) $sSubLine; - } - } - } - - $this->aCapa[] = $sCapa; - } - } - } - } - - /** - * @param string $sHost - * - * @return void - * - * @throws \MailSo\Net\Exceptions\Exception - * @throws \MailSo\Smtp\Exceptions\Exception - */ - private function helo($sHost) - { - $this->sendRequestWithCheck('HELO', 250, $sHost); - $this->aAuthTypes = array(); - $this->iSizeCapaValue = 0; - $this->aCapa = array(); - } - - /** - * @param int|array $mExpectCode - * @param string $sErrorPrefix = '' - * - * @return void - * - * @throws \MailSo\Smtp\Exceptions\ResponseException - */ - private function validateResponse($mExpectCode, $sErrorPrefix = '') - { - if (!\is_array($mExpectCode)) - { - $mExpectCode = array((int) $mExpectCode); - } - else - { - $mExpectCode = \array_map('intval', $mExpectCode); - } - - $aParts = array('', '', ''); - $this->aResults = array(); - do - { - $this->getNextBuffer(); - $aParts = \preg_split('/([\s\-]+)/', $this->sResponseBuffer, 2, PREG_SPLIT_DELIM_CAPTURE); - - if (\is_array($aParts) && 3 === \count($aParts) && \is_numeric($aParts[0])) - { - if ('-' !== \substr($aParts[1], 0, 1) && !\in_array((int) $aParts[0], $mExpectCode)) - { - $this->writeLogException( - new Exceptions\NegativeResponseException($this->aResults, - ('' === $sErrorPrefix ? '' : $sErrorPrefix.': ').\trim( - (0 < \count($this->aResults) ? \implode("\r\n", $this->aResults)."\r\n" : ''). - $this->sResponseBuffer)), \MailSo\Log\Enumerations\Type::ERROR, true); - } - } - else - { - $this->writeLogException( - new Exceptions\ResponseException($this->aResults, - ('' === $sErrorPrefix ? '' : $sErrorPrefix.': ').\trim( - (0 < \count($this->aResults) ? \implode("\r\n", $this->aResults)."\r\n" : ''). - $this->sResponseBuffer)), \MailSo\Log\Enumerations\Type::ERROR, true); - } - - $this->aResults[] = $this->sResponseBuffer; - } - while ('-' === \substr($aParts[1], 0, 1)); - - $this->writeLog((microtime(true) - $this->iRequestTime), - \MailSo\Log\Enumerations\Type::TIME); - } - - /** - * @return string - */ - protected function getLogName() - { - return 'SMTP'; - } - - /** - * @param \MailSo\Log\Logger $oLogger - * - * @return \MailSo\Smtp\SmtpClient - * - * @throws \MailSo\Base\Exceptions\InvalidArgumentException - */ - public function SetLogger($oLogger) - { - parent::SetLogger($oLogger); - - return $this; - } -} +aAuthTypes = array(); + + $this->iRequestTime = 0; + $this->iSizeCapaValue = 0; + $this->aResults = array(); + $this->aCapa = array(); + + $this->bHelo = false; + $this->bRcpt = false; + $this->bMail = false; + $this->bData = false; + } + + /** + * @return \MailSo\Smtp\SmtpClient + */ + public static function NewInstance() + { + return new self(); + } + + /** + * @return bool + */ + public function IsSupported($sCapa) + { + return in_array(strtoupper($sCapa), $this->aCapa); + } + + /** + * @return bool + */ + public function IsAuthSupported($sAuth) + { + return in_array(strtoupper($sAuth), $this->aAuthTypes); + } + + /** + * @return bool + */ + public function HasSupportedAuth() + { + return $this->IsAuthSupported('PLAIN') || $this->IsAuthSupported('LOGIN'); + } + + /** + * @return string + */ + public static function EhloHelper() + { + $sEhloHost = empty($_SERVER['SERVER_NAME']) ? '' : \trim($_SERVER['SERVER_NAME']); + if (empty($sEhloHost)) + { + $sEhloHost = empty($_SERVER['HTTP_HOST']) ? '' : \trim($_SERVER['HTTP_HOST']); + } + + if (empty($sEhloHost)) + { + $sEhloHost = \function_exists('gethostname') ? \gethostname() : 'localhost'; + } + + $sEhloHost = \trim(\preg_replace('/:\d+$/', '', \trim($sEhloHost))); + + if (\preg_match('/^\d+\.\d+\.\d+\.\d+$/', $sEhloHost)) + { + $sEhloHost = '['.$sEhloHost.']'; + } + + return empty($sEhloHost) ? 'localhost' : $sEhloHost; + } + + /** + * @param string $sServerName + * @param int $iPort = 25 + * @param string $sEhloHost = '[127.0.0.1]' + * @param int $iSecurityType = \MailSo\Net\Enumerations\ConnectionSecurityType::AUTO_DETECT + * @param bool $bVerifySsl = false + * @param bool $bAllowSelfSigned = true + * + * @return \MailSo\Smtp\SmtpClient + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Smtp\Exceptions\ResponseException + */ + public function Connect($sServerName, $iPort = 25, $sEhloHost = '[127.0.0.1]', + $iSecurityType = \MailSo\Net\Enumerations\ConnectionSecurityType::AUTO_DETECT, + $bVerifySsl = false, $bAllowSelfSigned = true) + { + $this->iRequestTime = microtime(true); + + parent::Connect($sServerName, $iPort, $iSecurityType, $bVerifySsl, $bAllowSelfSigned); + + $this->validateResponse(220); + + $this->preLoginStartTLSAndEhloProcess($sEhloHost); + + return $this; + } + + /** + * @param string $sLogin + * @param string $sPassword + * @param boolean $bUseAuthPlainIfSupported = true + * @param boolean $bUseAuthCramMd5IfSupported = true + * + * @return \MailSo\Smtp\SmtpClient + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Smtp\Exceptions\Exception + */ + public function Login($sLogin, $sPassword, $bUseAuthPlainIfSupported = true, $bUseAuthCramMd5IfSupported = true) + { + $sLogin = \MailSo\Base\Utils::IdnToAscii(\MailSo\Base\Utils::Trim($sLogin)); + + if ($bUseAuthCramMd5IfSupported && $this->IsAuthSupported('CRAM-MD5')) + { + try + { + $this->sendRequestWithCheck('AUTH', 334, 'CRAM-MD5'); + } + catch (\MailSo\Smtp\Exceptions\NegativeResponseException $oException) + { + $this->writeLogException( + new \MailSo\Smtp\Exceptions\LoginBadMethodException( + $oException->GetResponses(), $oException->getMessage(), 0, $oException), + \MailSo\Log\Enumerations\Type::NOTICE, true); + } + + $sTicket = ''; + + $sContinuationResponse = !empty($this->aResults[0]) ? \trim($this->aResults[0]) : ''; + if ($sContinuationResponse && '334 ' === \substr($sContinuationResponse, 0, 4) && 0 < \strlen(\substr($sContinuationResponse, 4))) + { + $sTicket = @\base64_decode(\substr($sContinuationResponse, 4)); + $this->writeLogWithCrlf('ticket: '.$sTicket); + } + + if (empty($sTicket)) + { + $this->writeLogException( + new \MailSo\Smtp\Exceptions\NegativeResponseException(), + \MailSo\Log\Enumerations\Type::NOTICE, true + ); + } + + try + { + $this->sendRequestWithCheck(\base64_encode($sLogin.' '.\MailSo\Base\Utils::Hmac($sTicket, $sPassword)), 235, '', true); + } + catch (\MailSo\Smtp\Exceptions\NegativeResponseException $oException) + { + $this->writeLogException( + new \MailSo\Smtp\Exceptions\LoginBadCredentialsException( + $oException->GetResponses(), $oException->getMessage(), 0, $oException), + \MailSo\Log\Enumerations\Type::NOTICE, true); + } + } + else if ($bUseAuthPlainIfSupported && $this->IsAuthSupported('PLAIN')) + { + if ($this->__USE_SINGLE_LINE_AUTH_PLAIN_COMMAND) + { + try + { + $this->sendRequestWithCheck('AUTH', 235, 'PLAIN '.\base64_encode("\0".$sLogin."\0".$sPassword), true); + } + catch (\MailSo\Smtp\Exceptions\NegativeResponseException $oException) + { + $this->writeLogException( + new \MailSo\Smtp\Exceptions\LoginBadCredentialsException( + $oException->GetResponses(), $oException->getMessage(), 0, $oException), + \MailSo\Log\Enumerations\Type::NOTICE, true); + } + } + else + { + try + { + $this->sendRequestWithCheck('AUTH', 334, 'PLAIN'); + } + catch (\MailSo\Smtp\Exceptions\NegativeResponseException $oException) + { + $this->writeLogException( + new \MailSo\Smtp\Exceptions\LoginBadMethodException( + $oException->GetResponses(), $oException->getMessage(), 0, $oException), + \MailSo\Log\Enumerations\Type::NOTICE, true); + } + + try + { + $this->sendRequestWithCheck(\base64_encode("\0".$sLogin."\0".$sPassword), 235, '', true); + } + catch (\MailSo\Smtp\Exceptions\NegativeResponseException $oException) + { + $this->writeLogException( + new \MailSo\Smtp\Exceptions\LoginBadCredentialsException( + $oException->GetResponses(), $oException->getMessage(), 0, $oException), + \MailSo\Log\Enumerations\Type::NOTICE, true); + } + } + } + else if ($this->IsAuthSupported('LOGIN')) + { + try + { + $this->sendRequestWithCheck('AUTH', 334, 'LOGIN'); + } + catch (\MailSo\Smtp\Exceptions\NegativeResponseException $oException) + { + $this->writeLogException( + new \MailSo\Smtp\Exceptions\LoginBadMethodException( + $oException->GetResponses(), $oException->getMessage(), 0, $oException), + \MailSo\Log\Enumerations\Type::NOTICE, true); + } + + try + { + $this->sendRequestWithCheck(\base64_encode($sLogin), 334, ''); + $this->sendRequestWithCheck(\base64_encode($sPassword), 235, '', true); + } + catch (\MailSo\Smtp\Exceptions\NegativeResponseException $oException) + { + $this->writeLogException( + new \MailSo\Smtp\Exceptions\LoginBadCredentialsException( + $oException->GetResponses(), $oException->getMessage(), 0, $oException), + \MailSo\Log\Enumerations\Type::NOTICE, true); + } + } + else + { + $this->writeLogException( + new \MailSo\Smtp\Exceptions\LoginBadMethodException(), + \MailSo\Log\Enumerations\Type::NOTICE, true); + } + + return $this; + } + + /** + * @param string $sXOAuth2Token + * + * @return \MailSo\Smtp\SmtpClient + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Smtp\Exceptions\Exception + */ + public function LoginWithXOauth2($sXOAuth2Token) + { + if ($this->IsAuthSupported('XOAUTH2')) + { + try + { + $this->sendRequestWithCheck('AUTH', 235, 'XOAUTH2 '.\trim($sXOAuth2Token)); + } + catch (\MailSo\Smtp\Exceptions\NegativeResponseException $oException) + { + $this->writeLogException( + new \MailSo\Smtp\Exceptions\LoginBadCredentialsException( + $oException->GetResponses(), $oException->getMessage(), 0, $oException), + \MailSo\Log\Enumerations\Type::NOTICE, true); + } + } + else + { + $this->writeLogException( + new \MailSo\Smtp\Exceptions\LoginBadMethodException(), + \MailSo\Log\Enumerations\Type::NOTICE, true); + } + + return $this; + } + + /** + * @param string $sFrom + * @param string $sSizeIfSupported = '' + * @param bool $bDsn = false + * + * @return \MailSo\Smtp\SmtpClient + * + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Smtp\Exceptions\Exception + */ + public function MailFrom($sFrom, $sSizeIfSupported = '', $bDsn = false) + { + $sFrom = \MailSo\Base\Utils::IdnToAscii( + \MailSo\Base\Utils::Trim($sFrom), true); + + $sCmd = 'FROM:<'.$sFrom.'>'; + + $sSizeIfSupported = (string) $sSizeIfSupported; + if (0 < \strlen($sSizeIfSupported) && \is_numeric($sSizeIfSupported) && $this->IsSupported('SIZE')) + { + $sCmd .= ' SIZE='.$sSizeIfSupported; + } + + if ($bDsn && $this->IsSupported('DSN')) + { + $sCmd .= ' RET=HDRS'; + } + + $this->sendRequestWithCheck('MAIL', 250, $sCmd); + + $this->bMail = true; + $this->bRcpt = false; + $this->bData = false; + + return $this; + } + + /** + * @param string $sTo + * @param bool $bDsn = false + * + * @return \MailSo\Smtp\SmtpClient + * + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Smtp\Exceptions\Exception + */ + public function Rcpt($sTo, $bDsn = false) + { + if (!$this->bMail) + { + $this->writeLogException( + new Exceptions\RuntimeException('No sender reverse path has been supplied'), + \MailSo\Log\Enumerations\Type::ERROR, true); + } + + $sTo = \MailSo\Base\Utils::IdnToAscii( + \MailSo\Base\Utils::Trim($sTo), true); + + $sCmd = 'TO:<'.$sTo.'>'; + + if ($bDsn && $this->IsSupported('DSN')) + { + $sCmd .= ' NOTIFY=SUCCESS,FAILURE'; + } + + $this->sendRequestWithCheck( + 'RCPT', array(250, 251), $sCmd, false, + 'Failed to add recipient "'.$sTo.'"' + ); + + $this->bRcpt = true; + + return $this; + } + + /** + * @param string $sTo + * + * @return \MailSo\Smtp\SmtpClient + * + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Smtp\Exceptions\Exception + */ + public function MailTo($sTo) + { + return $this->Rcpt($sTo); + } + + /** + * @param string $sData + * + * @return \MailSo\Smtp\SmtpClient + * + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Smtp\Exceptions\Exception + */ + public function Data($sData) + { + if (!\MailSo\Base\Validator::NotEmptyString($sData, true)) + { + throw new \MailSo\Base\Exceptions\InvalidArgumentException(); + } + + $rDataStream = \MailSo\Base\ResourceRegistry::CreateMemoryResourceFromString($sData); + unset($sData); + $this->DataWithStream($rDataStream); + \MailSo\Base\ResourceRegistry::CloseMemoryResource($rDataStream); + + return $this; + } + + /** + * @param resource $rDataStream + * + * @return \MailSo\Smtp\SmtpClient + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Smtp\Exceptions\Exception + */ + public function DataWithStream($rDataStream) + { + if (!\is_resource($rDataStream)) + { + throw new \MailSo\Base\Exceptions\InvalidArgumentException(); + } + + if (!$this->bRcpt) + { + $this->writeLogException( + new Exceptions\RuntimeException('No recipient forward path has been supplied'), + \MailSo\Log\Enumerations\Type::ERROR, true); + } + + $this->sendRequestWithCheck('DATA', 354); + + $this->writeLog('Message data.', \MailSo\Log\Enumerations\Type::NOTE); + + $this->bRunningCallback = true; + + while (!\feof($rDataStream)) + { + $sBuffer = \fgets($rDataStream); + if (false !== $sBuffer) + { + if (0 === \strpos($sBuffer, '.')) + { + $sBuffer = '.'.$sBuffer; + } + + $this->sendRaw(\rtrim($sBuffer, "\r\n"), false); + + \MailSo\Base\Utils::ResetTimeLimit(); + continue; + } + else if (!\feof($rDataStream)) + { + $this->writeLogException( + new Exceptions\RuntimeException('Cannot read input resource'), + \MailSo\Log\Enumerations\Type::ERROR, true); + } + + break; + } + + $this->sendRequestWithCheck('.', 250); + + $this->bRunningCallback = false; + + $this->bData = true; + + return $this; + } + + /** + * @return \MailSo\Smtp\SmtpClient + * + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Smtp\Exceptions\Exception + */ + public function Rset() + { + $this->sendRequestWithCheck('RSET', array(250, 220)); + + $this->bMail = false; + $this->bRcpt = false; + $this->bData = false; + + return $this; + } + + /** + * @return \MailSo\Smtp\SmtpClient + * + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Smtp\Exceptions\Exception + */ + public function Vrfy($sUser) + { + $sUser = \MailSo\Base\Utils::IdnToAscii( + \MailSo\Base\Utils::Trim($sUser)); + + $this->sendRequestWithCheck('VRFY', array(250, 251, 252), $sUser); + + return $this; + } + + /** + * @return \MailSo\Smtp\SmtpClient + * + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Smtp\Exceptions\Exception + */ + public function Noop() + { + $this->sendRequestWithCheck('NOOP', 250); + + return $this; + } + + /** + * @return \MailSo\Smtp\SmtpClient + * + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Smtp\Exceptions\Exception + */ + public function Logout() + { + if ($this->IsConnected()) + { + $this->sendRequestWithCheck('QUIT', 221); + } + + $this->bHelo = false; + $this->bMail = false; + $this->bRcpt = false; + $this->bData = false; + + return $this; + } + + /** + * @param string $sEhloHost + * + * @return void + */ + private function preLoginStartTLSAndEhloProcess($sEhloHost) + { + if ($this->bHelo) + { + $this->writeLogException( + new Exceptions\RuntimeException('Cannot issue EHLO/HELO to existing session'), + \MailSo\Log\Enumerations\Type::ERROR, true); + } + + $this->ehloOrHelo($sEhloHost); + + if (\MailSo\Net\Enumerations\ConnectionSecurityType::UseStartTLS( + $this->IsSupported('STARTTLS'), $this->iSecurityType, $this->HasSupportedAuth())) + { + $this->sendRequestWithCheck('STARTTLS', 220); + $this->EnableCrypto(); + + $this->ehloOrHelo($sEhloHost); + } + else if (\MailSo\Net\Enumerations\ConnectionSecurityType::STARTTLS === $this->iSecurityType) + { + $this->writeLogException( + new \MailSo\Net\Exceptions\SocketUnsuppoterdSecureConnectionException('STARTTLS is not supported'), + \MailSo\Log\Enumerations\Type::ERROR, true); + } + + $this->bHelo = true; + } + + /** + * @param string $sCommand + * @param string $sAddToCommand = '' + * @param bool $bSecureLog = false + * + * @return void + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + */ + private function sendRequest($sCommand, $sAddToCommand = '', $bSecureLog = false) + { + if (!\MailSo\Base\Validator::NotEmptyString($sCommand, true)) + { + $this->writeLogException( + new \MailSo\Base\Exceptions\InvalidArgumentException(), + \MailSo\Log\Enumerations\Type::ERROR, true); + } + + $this->IsConnected(true); + + $sCommand = \trim($sCommand); + $sRealCommand = $sCommand.(0 === \strlen($sAddToCommand) ? '' : ' '.$sAddToCommand); + + $sFakeCommand = ($bSecureLog) ? '********' : ''; + + $this->iRequestTime = \microtime(true); + $this->sendRaw($sRealCommand, true, $sFakeCommand); + + return $this; + } + + /** + * @param string $sCommand + * @param int|array $mExpectCode + * @param string $sAddToCommand = '' + * @param bool $bSecureLog = false + * @param string $sErrorPrefix = '' + * + * @return void + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Smtp\Exceptions\Exception + */ + private function sendRequestWithCheck($sCommand, $mExpectCode, $sAddToCommand = '', $bSecureLog = false, $sErrorPrefix = '') + { + $this->sendRequest($sCommand, $sAddToCommand, $bSecureLog); + $this->validateResponse($mExpectCode, $sErrorPrefix); + } + + /** + * @param string $sHost + * + * @return void + */ + private function ehloOrHelo($sHost) + { + try + { + $this->ehlo($sHost); + } + catch (\Exception $oException) + { + try + { + $this->helo($sHost); + } + catch (\Exception $oException) + { + throw $oException; + } + } + + return $this; + } + + /** + * @param string $sHost + * + * @return void + * + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Smtp\Exceptions\Exception + */ + private function ehlo($sHost) + { + $this->sendRequestWithCheck('EHLO', 250, $sHost); + + foreach ($this->aResults as $sLine) + { + $aMatch = array(); + if (\preg_match('/[\d]+[ \-](.+)$/', $sLine, $aMatch) && isset($aMatch[1]) && 0 < \strlen($aMatch[1])) + { + $sLine = \trim($aMatch[1]); + $aLine = \preg_split('/[ =]/', $sLine, 2); + if (\is_array($aLine) && 0 < \count($aLine) && !empty($aLine[0])) + { + $sCapa = \strtoupper($aLine[0]); + if (('AUTH' === $sCapa || 'SIZE' === $sCapa) && !empty($aLine[1])) + { + $sSubLine = \trim(\strtoupper($aLine[1])); + if (0 < \strlen($sSubLine)) + { + if ('AUTH' === $sCapa) + { + $this->aAuthTypes = \explode(' ', $sSubLine); + } + else if ('SIZE' === $sCapa && \is_numeric($sSubLine)) + { + $this->iSizeCapaValue = (int) $sSubLine; + } + } + } + + $this->aCapa[] = $sCapa; + } + } + } + } + + /** + * @param string $sHost + * + * @return void + * + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Smtp\Exceptions\Exception + */ + private function helo($sHost) + { + $this->sendRequestWithCheck('HELO', 250, $sHost); + $this->aAuthTypes = array(); + $this->iSizeCapaValue = 0; + $this->aCapa = array(); + } + + /** + * @param int|array $mExpectCode + * @param string $sErrorPrefix = '' + * + * @return void + * + * @throws \MailSo\Smtp\Exceptions\ResponseException + */ + private function validateResponse($mExpectCode, $sErrorPrefix = '') + { + if (!\is_array($mExpectCode)) + { + $mExpectCode = array((int) $mExpectCode); + } + else + { + $mExpectCode = \array_map('intval', $mExpectCode); + } + + $aParts = array('', '', ''); + $this->aResults = array(); + do + { + $this->getNextBuffer(); + $aParts = \preg_split('/([\s\-]+)/', $this->sResponseBuffer, 2, PREG_SPLIT_DELIM_CAPTURE); + + if (\is_array($aParts) && 3 === \count($aParts) && \is_numeric($aParts[0])) + { + if ('-' !== \substr($aParts[1], 0, 1) && !\in_array((int) $aParts[0], $mExpectCode)) + { + $this->writeLogException( + new Exceptions\NegativeResponseException($this->aResults, + ('' === $sErrorPrefix ? '' : $sErrorPrefix.': ').\trim( + (0 < \count($this->aResults) ? \implode("\r\n", $this->aResults)."\r\n" : ''). + $this->sResponseBuffer)), \MailSo\Log\Enumerations\Type::ERROR, true); + } + } + else + { + $this->writeLogException( + new Exceptions\ResponseException($this->aResults, + ('' === $sErrorPrefix ? '' : $sErrorPrefix.': ').\trim( + (0 < \count($this->aResults) ? \implode("\r\n", $this->aResults)."\r\n" : ''). + $this->sResponseBuffer)), \MailSo\Log\Enumerations\Type::ERROR, true); + } + + $this->aResults[] = $this->sResponseBuffer; + } + while ('-' === \substr($aParts[1], 0, 1)); + + $this->writeLog((microtime(true) - $this->iRequestTime), + \MailSo\Log\Enumerations\Type::TIME); + } + + /** + * @return string + */ + protected function getLogName() + { + return 'SMTP'; + } + + /** + * @param \MailSo\Log\Logger $oLogger + * + * @return \MailSo\Smtp\SmtpClient + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + */ + public function SetLogger($oLogger) + { + parent::SetLogger($oLogger); + + return $this; + } +} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Vendors/Net/IDNA2.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Vendors/Net/IDNA2.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Vendors/Net/IDNA2.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Vendors/Net/IDNA2.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Vendors/Net/IDNA2CustomExceptions.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Vendors/Net/IDNA2CustomExceptions.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Vendors/Net/IDNA2CustomExceptions.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Vendors/Net/IDNA2CustomExceptions.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Version.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Version.php similarity index 93% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Version.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Version.php index f17b2871a11ecb6e6902055ba453159c76008e83..fd79b51d2dc5e4380a4bd9baffd49411f18db0c6 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/MailSo/Version.php +++ b/rainloop/app/rainloop/v/1.12.1/app/libraries/MailSo/Version.php @@ -1,59 +1,59 @@ -getSignature(); - } - - return $sSignature; - } -} +getSignature(); + } + + return $sSignature; + } +} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Mobile_Detect/LICENSE.txt b/rainloop/app/rainloop/v/1.12.1/app/libraries/Mobile_Detect/LICENSE.txt similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Mobile_Detect/LICENSE.txt rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Mobile_Detect/LICENSE.txt diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Mobile_Detect/Mobile_Detect.json b/rainloop/app/rainloop/v/1.12.1/app/libraries/Mobile_Detect/Mobile_Detect.json similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Mobile_Detect/Mobile_Detect.json rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Mobile_Detect/Mobile_Detect.json diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Mobile_Detect/Mobile_Detect.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Mobile_Detect/Mobile_Detect.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Mobile_Detect/Mobile_Detect.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Mobile_Detect/Mobile_Detect.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Mobile_Detect/README.md b/rainloop/app/rainloop/v/1.12.1/app/libraries/Mobile_Detect/README.md similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Mobile_Detect/README.md rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Mobile_Detect/README.md diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Mobile_Detect/composer.json b/rainloop/app/rainloop/v/1.12.1/app/libraries/Mobile_Detect/composer.json similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Mobile_Detect/composer.json rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Mobile_Detect/composer.json diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Mobile_Detect/namespaced/Detection/MobileDetect.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Mobile_Detect/namespaced/Detection/MobileDetect.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Mobile_Detect/namespaced/Detection/MobileDetect.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Mobile_Detect/namespaced/Detection/MobileDetect.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Mobile_Detect/ruleset.xml b/rainloop/app/rainloop/v/1.12.1/app/libraries/Mobile_Detect/ruleset.xml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Mobile_Detect/ruleset.xml rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Mobile_Detect/ruleset.xml diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/PHP-OAuth2/Client.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/PHP-OAuth2/Client.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/PHP-OAuth2/Client.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/PHP-OAuth2/Client.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/PHP-OAuth2/GrantType/AuthorizationCode.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/PHP-OAuth2/GrantType/AuthorizationCode.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/PHP-OAuth2/GrantType/AuthorizationCode.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/PHP-OAuth2/GrantType/AuthorizationCode.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/PHP-OAuth2/GrantType/ClientCredentials.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/PHP-OAuth2/GrantType/ClientCredentials.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/PHP-OAuth2/GrantType/ClientCredentials.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/PHP-OAuth2/GrantType/ClientCredentials.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/PHP-OAuth2/GrantType/IGrantType.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/PHP-OAuth2/GrantType/IGrantType.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/PHP-OAuth2/GrantType/IGrantType.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/PHP-OAuth2/GrantType/IGrantType.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/PHP-OAuth2/GrantType/Password.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/PHP-OAuth2/GrantType/Password.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/PHP-OAuth2/GrantType/Password.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/PHP-OAuth2/GrantType/Password.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/PHP-OAuth2/GrantType/RefreshToken.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/PHP-OAuth2/GrantType/RefreshToken.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/PHP-OAuth2/GrantType/RefreshToken.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/PHP-OAuth2/GrantType/RefreshToken.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/PHP-OAuth2/README b/rainloop/app/rainloop/v/1.12.1/app/libraries/PHP-OAuth2/README similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/PHP-OAuth2/README rename to rainloop/app/rainloop/v/1.12.1/app/libraries/PHP-OAuth2/README diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/PHPGangsta/GoogleAuthenticator.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/PHPGangsta/GoogleAuthenticator.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/PHPGangsta/GoogleAuthenticator.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/PHPGangsta/GoogleAuthenticator.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/PHPThumb/GD.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/PHPThumb/GD.php similarity index 97% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/PHPThumb/GD.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/PHPThumb/GD.php index 53469eda3a8e72fc2e2bd033188ccd7b80d0e021..733fe476c0cd74d1414fc68b1b353e403025b226 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/PHPThumb/GD.php +++ b/rainloop/app/rainloop/v/1.12.1/app/libraries/PHPThumb/GD.php @@ -1,1417 +1,1417 @@ - - * Copyright (c) 2009, Ian Selby/Gen X Design - * - * Author(s): Ian Selby - * - * Licensed under the MIT License - * Redistributions of files must retain the above copyright notice. - * - * @author Ian Selby - * @copyright Copyright (c) 2009 Gen X Design - * @link http://phpthumb.gxdlabs.com - * @license http://www.opensource.org/licenses/mit-license.php The MIT License - */ - -class GD extends PHPThumb -{ - /** - * The prior image (before manipulation) - * - * @var resource - */ - protected $oldImage; - - /** - * The working image (used during manipulation) - * - * @var resource - */ - protected $workingImage; - - /** - * The current dimensions of the image - * - * @var array - */ - protected $currentDimensions; - - /** - * The new, calculated dimensions of the image - * - * @var array - */ - protected $newDimensions; - - /** - * The options for this class - * - * This array contains various options that determine the behavior in - * various functions throughout the class. Functions note which specific - * option key / values are used in their documentation - * - * @var array - */ - protected $options; - - /** - * The maximum width an image can be after resizing (in pixels) - * - * @var int - */ - protected $maxWidth; - - /** - * The maximum height an image can be after resizing (in pixels) - * - * @var int - */ - protected $maxHeight; - - /** - * The percentage to resize the image by - * - * @var int - */ - protected $percent; - - /** - * @param string $fileName - * @param array $options - * @param array $plugins - */ - public function __construct($fileName, $options = array(), array $plugins = array()) - { - parent::__construct($fileName, $options, $plugins); - - $this->determineFormat(); - $this->verifyFormatCompatiblity(); - - switch ($this->format) { - case 'GIF': - $this->oldImage = @imagecreatefromgif($this->fileName); - break; - case 'JPG': - $this->oldImage = @imagecreatefromjpeg($this->fileName); - break; - case 'PNG': - $this->oldImage = @imagecreatefrompng($this->fileName); - break; - case 'STRING': - $this->oldImage = @imagecreatefromstring($this->fileName); - break; - } - - if (!is_resource($this->oldImage)) - { - throw new \Exception('Invalid image file'); - } - else - { - $this->currentDimensions = array ( - 'width' => imagesx($this->oldImage), - 'height' => imagesy($this->oldImage) - ); - } - } - - public function __destruct() - { - if (is_resource($this->oldImage)) { - imagedestroy($this->oldImage); - } - - if (is_resource($this->workingImage)) { - imagedestroy($this->workingImage); - } - } - - /** - * Pad an image to desired dimensions. Moves the image into the center and fills the rest with $color. - * @param $width - * @param $height - * @param array $color - * @return GD - */ - public function pad($width, $height, $color = array(255, 255, 255)) - { - // no resize - woohoo! - if ($width == $this->currentDimensions['width'] && $height == $this->currentDimensions['height']) { - return $this; - } - - // create the working image - if (function_exists('imagecreatetruecolor')) { - $this->workingImage = imagecreatetruecolor($width, $height); - } else { - $this->workingImage = imagecreate($width, $height); - } - - // create the fill color - $fillColor = imagecolorallocate( - $this->workingImage, - $color[0], - $color[1], - $color[2] - ); - - // fill our working image with the fill color - imagefill( - $this->workingImage, - 0, - 0, - $fillColor - ); - - // copy the image into the center of our working image - imagecopyresampled( - $this->workingImage, - $this->oldImage, - intval(($width-$this->currentDimensions['width']) / 2), - intval(($height-$this->currentDimensions['height']) / 2), - 0, - 0, - $this->currentDimensions['width'], - $this->currentDimensions['height'], - $this->currentDimensions['width'], - $this->currentDimensions['height'] - ); - - // update all the variables and resources to be correct - $this->oldImage = $this->workingImage; - $this->currentDimensions['width'] = $width; - $this->currentDimensions['height'] = $height; - - return $this; - } - - /** - * Resizes an image to be no larger than $maxWidth or $maxHeight - * - * If either param is set to zero, then that dimension will not be considered as a part of the resize. - * Additionally, if $this->options['resizeUp'] is set to true (false by default), then this function will - * also scale the image up to the maximum dimensions provided. - * - * @param int $maxWidth The maximum width of the image in pixels - * @param int $maxHeight The maximum height of the image in pixels - * @return \PHPThumb\GD - */ - public function resize($maxWidth = 0, $maxHeight = 0) - { - // make sure our arguments are valid - if (!is_numeric($maxWidth)) { - throw new \InvalidArgumentException('$maxWidth must be numeric'); - } - - if (!is_numeric($maxHeight)) { - throw new \InvalidArgumentException('$maxHeight must be numeric'); - } - - // make sure we're not exceeding our image size if we're not supposed to - if ($this->options['resizeUp'] === false) { - $this->maxHeight = (intval($maxHeight) > $this->currentDimensions['height']) ? $this->currentDimensions['height'] : $maxHeight; - $this->maxWidth = (intval($maxWidth) > $this->currentDimensions['width']) ? $this->currentDimensions['width'] : $maxWidth; - } else { - $this->maxHeight = intval($maxHeight); - $this->maxWidth = intval($maxWidth); - } - - // get the new dimensions... - $this->calcImageSize($this->currentDimensions['width'], $this->currentDimensions['height']); - - // create the working image - if (function_exists('imagecreatetruecolor')) { - $this->workingImage = imagecreatetruecolor($this->newDimensions['newWidth'], $this->newDimensions['newHeight']); - } else { - $this->workingImage = imagecreate($this->newDimensions['newWidth'], $this->newDimensions['newHeight']); - } - - $this->preserveAlpha(); - - // and create the newly sized image - imagecopyresampled( - $this->workingImage, - $this->oldImage, - 0, - 0, - 0, - 0, - $this->newDimensions['newWidth'], - $this->newDimensions['newHeight'], - $this->currentDimensions['width'], - $this->currentDimensions['height'] - ); - - // update all the variables and resources to be correct - $this->oldImage = $this->workingImage; - $this->currentDimensions['width'] = $this->newDimensions['newWidth']; - $this->currentDimensions['height'] = $this->newDimensions['newHeight']; - - return $this; - } - - /** - * Adaptively Resizes the Image - * - * This function attempts to get the image to as close to the provided dimensions as possible, and then crops the - * remaining overflow (from the center) to get the image to be the size specified - * - * @param int $maxWidth - * @param int $maxHeight - * @return \PHPThumb\GD - */ - public function adaptiveResize($width, $height) - { - // make sure our arguments are valid - if ((!is_numeric($width) || $width == 0) && (!is_numeric($height) || $height == 0)) { - throw new \InvalidArgumentException('$width and $height must be numeric and greater than zero'); - } - - if (!is_numeric($width) || $width == 0) { - $width = ($height * $this->currentDimensions['width']) / $this->currentDimensions['height']; - } - - if (!is_numeric($height) || $height == 0) { - $height = ($width * $this->currentDimensions['height']) / $this->currentDimensions['width']; - } - - // make sure we're not exceeding our image size if we're not supposed to - if ($this->options['resizeUp'] === false) { - $this->maxHeight = (intval($height) > $this->currentDimensions['height']) ? $this->currentDimensions['height'] : $height; - $this->maxWidth = (intval($width) > $this->currentDimensions['width']) ? $this->currentDimensions['width'] : $width; - } else { - $this->maxHeight = intval($height); - $this->maxWidth = intval($width); - } - - $this->calcImageSizeStrict($this->currentDimensions['width'], $this->currentDimensions['height']); - - // resize the image to be close to our desired dimensions - $this->resize($this->newDimensions['newWidth'], $this->newDimensions['newHeight']); - - // reset the max dimensions... - if ($this->options['resizeUp'] === false) { - $this->maxHeight = (intval($height) > $this->currentDimensions['height']) ? $this->currentDimensions['height'] : $height; - $this->maxWidth = (intval($width) > $this->currentDimensions['width']) ? $this->currentDimensions['width'] : $width; - } else { - $this->maxHeight = intval($height); - $this->maxWidth = intval($width); - } - - // create the working image - if (function_exists('imagecreatetruecolor')) { - $this->workingImage = imagecreatetruecolor($this->maxWidth, $this->maxHeight); - } else { - $this->workingImage = imagecreate($this->maxWidth, $this->maxHeight); - } - - $this->preserveAlpha(); - - $cropWidth = $this->maxWidth; - $cropHeight = $this->maxHeight; - $cropX = 0; - $cropY = 0; - - // now, figure out how to crop the rest of the image... - if ($this->currentDimensions['width'] > $this->maxWidth) { - $cropX = intval(($this->currentDimensions['width'] - $this->maxWidth) / 2); - } elseif ($this->currentDimensions['height'] > $this->maxHeight) { - $cropY = intval(($this->currentDimensions['height'] - $this->maxHeight) / 2); - } - - imagecopyresampled( - $this->workingImage, - $this->oldImage, - 0, - 0, - $cropX, - $cropY, - $cropWidth, - $cropHeight, - $cropWidth, - $cropHeight - ); - - // update all the variables and resources to be correct - $this->oldImage = $this->workingImage; - $this->currentDimensions['width'] = $this->maxWidth; - $this->currentDimensions['height'] = $this->maxHeight; - - return $this; - } - - /** - * Adaptively Resizes the Image and Crops Using a Percentage - * - * This function attempts to get the image to as close to the provided dimensions as possible, and then crops the - * remaining overflow using a provided percentage to get the image to be the size specified. - * - * The percentage mean different things depending on the orientation of the original image. - * - * For Landscape images: - * --------------------- - * - * A percentage of 1 would crop the image all the way to the left, which would be the same as - * using adaptiveResizeQuadrant() with $quadrant = 'L' - * - * A percentage of 50 would crop the image to the center which would be the same as using - * adaptiveResizeQuadrant() with $quadrant = 'C', or even the original adaptiveResize() - * - * A percentage of 100 would crop the image to the image all the way to the right, etc, etc. - * Note that you can use any percentage between 1 and 100. - * - * For Portrait images: - * -------------------- - * - * This works the same as for Landscape images except that a percentage of 1 means top and 100 means bottom - * - * @param int $maxWidth - * @param int $maxHeight - * @param int $percent - * @return \PHPThumb\GD - */ - public function adaptiveResizePercent($width, $height, $percent = 50) - { - // make sure our arguments are valid - if (!is_numeric($width) || $width == 0) { - throw new \InvalidArgumentException('$width must be numeric and greater than zero'); - } - - if (!is_numeric($height) || $height == 0) { - throw new \InvalidArgumentException('$height must be numeric and greater than zero'); - } - - // make sure we're not exceeding our image size if we're not supposed to - if ($this->options['resizeUp'] === false) { - $this->maxHeight = (intval($height) > $this->currentDimensions['height']) ? $this->currentDimensions['height'] : $height; - $this->maxWidth = (intval($width) > $this->currentDimensions['width']) ? $this->currentDimensions['width'] : $width; - } else { - $this->maxHeight = intval($height); - $this->maxWidth = intval($width); - } - - $this->calcImageSizeStrict($this->currentDimensions['width'], $this->currentDimensions['height']); - - // resize the image to be close to our desired dimensions - $this->resize($this->newDimensions['newWidth'], $this->newDimensions['newHeight']); - - // reset the max dimensions... - if ($this->options['resizeUp'] === false) { - $this->maxHeight = (intval($height) > $this->currentDimensions['height']) ? $this->currentDimensions['height'] : $height; - $this->maxWidth = (intval($width) > $this->currentDimensions['width']) ? $this->currentDimensions['width'] : $width; - } else { - $this->maxHeight = intval($height); - $this->maxWidth = intval($width); - } - - // create the working image - if (function_exists('imagecreatetruecolor')) { - $this->workingImage = imagecreatetruecolor($this->maxWidth, $this->maxHeight); - } else { - $this->workingImage = imagecreate($this->maxWidth, $this->maxHeight); - } - - $this->preserveAlpha(); - - $cropWidth = $this->maxWidth; - $cropHeight = $this->maxHeight; - $cropX = 0; - $cropY = 0; - - // Crop the rest of the image using the quadrant - - if ($percent > 100) { - $percent = 100; - } elseif ($percent < 1) { - $percent = 1; - } - - if ($this->currentDimensions['width'] > $this->maxWidth) { - // Image is landscape - $maxCropX = $this->currentDimensions['width'] - $this->maxWidth; - $cropX = intval(($percent / 100) * $maxCropX); - - } elseif ($this->currentDimensions['height'] > $this->maxHeight) { - // Image is portrait - $maxCropY = $this->currentDimensions['height'] - $this->maxHeight; - $cropY = intval(($percent / 100) * $maxCropY); - } - - imagecopyresampled( - $this->workingImage, - $this->oldImage, - 0, - 0, - $cropX, - $cropY, - $cropWidth, - $cropHeight, - $cropWidth, - $cropHeight - ); - - // update all the variables and resources to be correct - $this->oldImage = $this->workingImage; - $this->currentDimensions['width'] = $this->maxWidth; - $this->currentDimensions['height'] = $this->maxHeight; - - return $this; - } - - /** - * Adaptively Resizes the Image and Crops Using a Quadrant - * - * This function attempts to get the image to as close to the provided dimensions as possible, and then crops the - * remaining overflow using the quadrant to get the image to be the size specified. - * - * The quadrants available are Top, Bottom, Center, Left, and Right: - * - * - * +---+---+---+ - * | | T | | - * +---+---+---+ - * | L | C | R | - * +---+---+---+ - * | | B | | - * +---+---+---+ - * - * Note that if your image is Landscape and you choose either of the Top or Bottom quadrants (which won't - * make sence since only the Left and Right would be available, then the Center quadrant will be used - * to crop. This would have exactly the same result as using adaptiveResize(). - * The same goes if your image is portrait and you choose either the Left or Right quadrants. - * - * @param int $maxWidth - * @param int $maxHeight - * @param string $quadrant T, B, C, L, R - * @return \PHPThumb\GD - */ - public function adaptiveResizeQuadrant($width, $height, $quadrant = 'C') - { - // make sure our arguments are valid - if (!is_numeric($width) || $width == 0) { - throw new \InvalidArgumentException('$width must be numeric and greater than zero'); - } - - if (!is_numeric($height) || $height == 0) { - throw new \InvalidArgumentException('$height must be numeric and greater than zero'); - } - - // make sure we're not exceeding our image size if we're not supposed to - if ($this->options['resizeUp'] === false) { - $this->maxHeight = (intval($height) > $this->currentDimensions['height']) ? $this->currentDimensions['height'] : $height; - $this->maxWidth = (intval($width) > $this->currentDimensions['width']) ? $this->currentDimensions['width'] : $width; - } else { - $this->maxHeight = intval($height); - $this->maxWidth = intval($width); - } - - $this->calcImageSizeStrict($this->currentDimensions['width'], $this->currentDimensions['height']); - - // resize the image to be close to our desired dimensions - $this->resize($this->newDimensions['newWidth'], $this->newDimensions['newHeight']); - - // reset the max dimensions... - if ($this->options['resizeUp'] === false) { - $this->maxHeight = (intval($height) > $this->currentDimensions['height']) ? $this->currentDimensions['height'] : $height; - $this->maxWidth = (intval($width) > $this->currentDimensions['width']) ? $this->currentDimensions['width'] : $width; - } else { - $this->maxHeight = intval($height); - $this->maxWidth = intval($width); - } - - // create the working image - if (function_exists('imagecreatetruecolor')) { - $this->workingImage = imagecreatetruecolor($this->maxWidth, $this->maxHeight); - } else { - $this->workingImage = imagecreate($this->maxWidth, $this->maxHeight); - } - - $this->preserveAlpha(); - - $cropWidth = $this->maxWidth; - $cropHeight = $this->maxHeight; - $cropX = 0; - $cropY = 0; - - // Crop the rest of the image using the quadrant - - if ($this->currentDimensions['width'] > $this->maxWidth) { - // Image is landscape - switch ($quadrant) { - case 'L': - $cropX = 0; - break; - case 'R': - $cropX = intval(($this->currentDimensions['width'] - $this->maxWidth)); - break; - case 'C': - default: - $cropX = intval(($this->currentDimensions['width'] - $this->maxWidth) / 2); - break; - } - } elseif ($this->currentDimensions['height'] > $this->maxHeight) { - // Image is portrait - switch ($quadrant) { - case 'T': - $cropY = 0; - break; - case 'B': - $cropY = intval(($this->currentDimensions['height'] - $this->maxHeight)); - break; - case 'C': - default: - $cropY = intval(($this->currentDimensions['height'] - $this->maxHeight) / 2); - break; - } - } - - imagecopyresampled( - $this->workingImage, - $this->oldImage, - 0, - 0, - $cropX, - $cropY, - $cropWidth, - $cropHeight, - $cropWidth, - $cropHeight - ); - - // update all the variables and resources to be correct - $this->oldImage = $this->workingImage; - $this->currentDimensions['width'] = $this->maxWidth; - $this->currentDimensions['height'] = $this->maxHeight; - - return $this; - } - - /** - * Resizes an image by a given percent uniformly, - * Percentage should be whole number representation (i.e. 1-100) - * - * @param int $percent - * @return GD - * @throws \InvalidArgumentException - */ - public function resizePercent($percent = 0) - { - if (!is_numeric($percent)) { - throw new \InvalidArgumentException ('$percent must be numeric'); - } - - $this->percent = intval($percent); - - $this->calcImageSizePercent($this->currentDimensions['width'], $this->currentDimensions['height']); - - if (function_exists('imagecreatetruecolor')) { - $this->workingImage = imagecreatetruecolor($this->newDimensions['newWidth'], $this->newDimensions['newHeight']); - } else { - $this->workingImage = imagecreate($this->newDimensions['newWidth'], $this->newDimensions['newHeight']); - } - - $this->preserveAlpha(); - - imagecopyresampled( - $this->workingImage, - $this->oldImage, - 0, - 0, - 0, - 0, - $this->newDimensions['newWidth'], - $this->newDimensions['newHeight'], - $this->currentDimensions['width'], - $this->currentDimensions['height'] - ); - - $this->oldImage = $this->workingImage; - $this->currentDimensions['width'] = $this->newDimensions['newWidth']; - $this->currentDimensions['height'] = $this->newDimensions['newHeight']; - - return $this; - } - - /** - * Crops an image from the center with provided dimensions - * - * If no height is given, the width will be used as a height, thus creating a square crop - * - * @param int $cropWidth - * @param int $cropHeight - * @return \PHPThumb\GD - */ - public function cropFromCenter($cropWidth, $cropHeight = null) - { - if (!is_numeric($cropWidth)) { - throw new \InvalidArgumentException('$cropWidth must be numeric'); - } - - if ($cropHeight !== null && !is_numeric($cropHeight)) { - throw new \InvalidArgumentException('$cropHeight must be numeric'); - } - - if ($cropHeight === null) { - $cropHeight = $cropWidth; - } - - $cropWidth = ($this->currentDimensions['width'] < $cropWidth) ? $this->currentDimensions['width'] : $cropWidth; - $cropHeight = ($this->currentDimensions['height'] < $cropHeight) ? $this->currentDimensions['height'] : $cropHeight; - - $cropX = intval(($this->currentDimensions['width'] - $cropWidth) / 2); - $cropY = intval(($this->currentDimensions['height'] - $cropHeight) / 2); - - $this->crop($cropX, $cropY, $cropWidth, $cropHeight); - - return $this; - } - - /** - * Vanilla Cropping - Crops from x,y with specified width and height - * - * @param int $startX - * @param int $startY - * @param int $cropWidth - * @param int $cropHeight - * @return \PHPThumb\GD - */ - public function crop($startX, $startY, $cropWidth, $cropHeight) - { - // validate input - if (!is_numeric($startX)) { - throw new \InvalidArgumentException('$startX must be numeric'); - } - - if (!is_numeric($startY)) { - throw new \InvalidArgumentException('$startY must be numeric'); - } - - if (!is_numeric($cropWidth)) { - throw new \InvalidArgumentException('$cropWidth must be numeric'); - } - - if (!is_numeric($cropHeight)) { - throw new \InvalidArgumentException('$cropHeight must be numeric'); - } - - // do some calculations - $cropWidth = ($this->currentDimensions['width'] < $cropWidth) ? $this->currentDimensions['width'] : $cropWidth; - $cropHeight = ($this->currentDimensions['height'] < $cropHeight) ? $this->currentDimensions['height'] : $cropHeight; - - // ensure everything's in bounds - if (($startX + $cropWidth) > $this->currentDimensions['width']) { - $startX = ($this->currentDimensions['width'] - $cropWidth); - } - - if (($startY + $cropHeight) > $this->currentDimensions['height']) { - $startY = ($this->currentDimensions['height'] - $cropHeight); - } - - if ($startX < 0) { - $startX = 0; - } - - if ($startY < 0) { - $startY = 0; - } - - // create the working image - if (function_exists('imagecreatetruecolor')) { - $this->workingImage = imagecreatetruecolor($cropWidth, $cropHeight); - } else { - $this->workingImage = imagecreate($cropWidth, $cropHeight); - } - - $this->preserveAlpha(); - - imagecopyresampled( - $this->workingImage, - $this->oldImage, - 0, - 0, - $startX, - $startY, - $cropWidth, - $cropHeight, - $cropWidth, - $cropHeight - ); - - $this->oldImage = $this->workingImage; - $this->currentDimensions['width'] = $cropWidth; - $this->currentDimensions['height'] = $cropHeight; - - return $this; - } - - /** - * Rotates image either 90 degrees clockwise or counter-clockwise - * - * @param string $direction - * @retunrn \PHPThumb\GD - */ - public function rotateImage($direction = 'CW') - { - if ($direction == 'CW') { - $this->rotateImageNDegrees(90); - } else { - $this->rotateImageNDegrees(-90); - } - - return $this; - } - - /** - * Rotates image specified number of degrees - * - * @param int $degrees - * @return \PHPThumb\GD - */ - public function rotateImageNDegrees($degrees) - { - if (!is_numeric($degrees)) { - throw new \InvalidArgumentException('$degrees must be numeric'); - } - - if (!function_exists('imagerotate')) { - throw new \RuntimeException('Your version of GD does not support image rotation'); - } - - $this->workingImage = imagerotate($this->oldImage, $degrees, 0); - - $newWidth = $this->currentDimensions['height']; - $newHeight = $this->currentDimensions['width']; - $this->oldImage = $this->workingImage; - $this->currentDimensions['width'] = $newWidth; - $this->currentDimensions['height'] = $newHeight; - - return $this; - } - - /** - * Applies a filter to the image - * - * @param int $filter - * @return \PHPThumb\GD - */ - public function imageFilter($filter, $arg1 = false, $arg2 = false, $arg3 = false, $arg4 = false) - { - if (!is_numeric($filter)) { - throw new \InvalidArgumentException('$filter must be numeric'); - } - - if (!function_exists('imagefilter')) { - throw new \RuntimeException('Your version of GD does not support image filters'); - } - - $result = false; - if ($arg1 === false) { - $result = imagefilter($this->oldImage, $filter); - } elseif ($arg2 === false) { - $result = imagefilter($this->oldImage, $filter, $arg1); - } elseif ($arg3 === false) { - $result = imagefilter($this->oldImage, $filter, $arg1, $arg2); - } elseif ($arg4 === false) { - $result = imagefilter($this->oldImage, $filter, $arg1, $arg2, $arg3); - } else { - $result = imagefilter($this->oldImage, $filter, $arg1, $arg2, $arg3, $arg4); - } - - if (!$result) { - throw new \RuntimeException('GD imagefilter failed'); - } - - $this->workingImage = $this->oldImage; - - return $this; - } - - /** - * Shows an image - * - * This function will show the current image by first sending the appropriate header - * for the format, and then outputting the image data. If headers have already been sent, - * a runtime exception will be thrown - * - * @param bool $rawData Whether or not the raw image stream should be output - * @return \PHPThumb\GD - */ - public function show($rawData = false) - { - //Execute any plugins - if ($this->plugins) { - foreach ($this->plugins as $plugin) { - /* @var $plugin \PHPThumb\PluginInterface */ - $plugin->execute($this); - } - } - - if (headers_sent() && php_sapi_name() != 'cli') { - throw new \RuntimeException('Cannot show image, headers have already been sent'); - } - - // When the interlace option equals true or false call imageinterlace else leave it to default - if ($this->options['interlace'] === true) { - imageinterlace($this->oldImage, 1); - } elseif ($this->options['interlace'] === false) { - imageinterlace($this->oldImage, 0); - } - - switch ($this->format) { - case 'GIF': - if ($rawData === false) { - header('Content-type: image/gif'); - } - imagegif($this->oldImage); - break; - case 'JPG': - if ($rawData === false) { - header('Content-type: image/jpeg'); - } - imagejpeg($this->oldImage, null, $this->options['jpegQuality']); - break; - case 'PNG': - case 'STRING': - if ($rawData === false) { - header('Content-type: image/png'); - } - imagepng($this->oldImage); - break; - } - - return $this; - } - - /** - * Returns the Working Image as a String - * - * This function is useful for getting the raw image data as a string for storage in - * a database, or other similar things. - * - * @return string - */ - public function getImageAsString() - { - $data = null; - ob_start(); - $this->show(true); - $data = ob_get_contents(); - ob_end_clean(); - - return $data; - } - - /** - * Saves an image - * - * This function will make sure the target directory is writeable, and then save the image. - * - * If the target directory is not writeable, the function will try to correct the permissions (if allowed, this - * is set as an option ($this->options['correctPermissions']). If the target cannot be made writeable, then a - * \RuntimeException is thrown. - * - * @param string $fileName The full path and filename of the image to save - * @param string $format The format to save the image in (optional, must be one of [GIF,JPG,PNG] - * @return \PHPThumb\GD - */ - public function save($fileName, $format = null) - { - $validFormats = array('GIF', 'JPG', 'PNG'); - $format = ($format !== null) ? strtoupper($format) : $this->format; - - if (!in_array($format, $validFormats)) { - throw new \InvalidArgumentException("Invalid format type specified in save function: {$format}"); - } - - // make sure the directory is writeable - if (!is_writeable(dirname($fileName))) { - // try to correct the permissions - if ($this->options['correctPermissions'] === true) { - @chmod(dirname($fileName), 0777); - - // throw an exception if not writeable - if (!is_writeable(dirname($fileName))) { - throw new \RuntimeException("File is not writeable, and could not correct permissions: {$fileName}"); - } - } else { // throw an exception if not writeable - throw new \RuntimeException("File not writeable: {$fileName}"); - } - } - - // When the interlace option equals true or false call imageinterlace else leave it to default - if ($this->options['interlace'] === true) { - imageinterlace($this->oldImage, 1); - } elseif ($this->options['interlace'] === false) { - imageinterlace($this->oldImage, 0); - } - - switch ($format) { - case 'GIF': - imagegif($this->oldImage, $fileName); - break; - case 'JPG': - imagejpeg($this->oldImage, $fileName, $this->options['jpegQuality']); - break; - case 'PNG': - imagepng($this->oldImage, $fileName); - break; - } - - return $this; - } - - ################################# - # ----- GETTERS / SETTERS ----- # - ################################# - - /** - * Sets options for all operations. - * @param array $options - * @return GD - */ - public function setOptions(array $options = array()) - { - // we've yet to init the default options, so create them here - if (sizeof($this->options) == 0) { - $defaultOptions = array( - 'resizeUp' => false, - 'jpegQuality' => 100, - 'correctPermissions' => false, - 'preserveAlpha' => true, - 'alphaMaskColor' => array (255, 255, 255), - 'preserveTransparency' => true, - 'transparencyMaskColor' => array (0, 0, 0), - 'interlace' => null - ); - } else { // otherwise, let's use what we've got already - $defaultOptions = $this->options; - } - - $this->options = array_merge($defaultOptions, $options); - - return $this; - } - - /** - * Returns $currentDimensions. - * - * @see \PHPThumb\GD::$currentDimensions - */ - public function getCurrentDimensions() - { - return $this->currentDimensions; - } - - /** - * @param $currentDimensions - * @return GD - */ - public function setCurrentDimensions($currentDimensions) - { - $this->currentDimensions = $currentDimensions; - - return $this; - } - - /** - * @return int - */ - public function getMaxHeight() - { - return $this->maxHeight; - } - - /** - * @param $maxHeight - * @return GD - */ - public function setMaxHeight($maxHeight) - { - $this->maxHeight = $maxHeight; - - return $this; - } - - /** - * @return int - */ - public function getMaxWidth() - { - return $this->maxWidth; - } - - /** - * @param $maxWidth - * @return GD - */ - public function setMaxWidth($maxWidth) - { - $this->maxWidth = $maxWidth; - - return $this; - } - - /** - * Returns $newDimensions. - * - * @see \PHPThumb\GD::$newDimensions - */ - public function getNewDimensions() - { - return $this->newDimensions; - } - - /** - * Sets $newDimensions. - * - * @param object $newDimensions - * @see \PHPThumb\GD::$newDimensions - */ - public function setNewDimensions($newDimensions) - { - $this->newDimensions = $newDimensions; - - return $this; - } - - /** - * Returns $options. - * - * @see \PHPThumb\GD::$options - */ - public function getOptions() - { - return $this->options; - } - - /** - * Returns $percent. - * - * @see \PHPThumb\GD::$percent - */ - public function getPercent() - { - return $this->percent; - } - - /** - * Sets $percent. - * - * @param object $percent - * @see \PHPThumb\GD::$percent - */ - public function setPercent($percent) - { - $this->percent = $percent; - - return $this; - } - - /** - * Returns $oldImage. - * - * @see \PHPThumb\GD::$oldImage - */ - public function getOldImage() - { - return $this->oldImage; - } - - /** - * Sets $oldImage. - * - * @param object $oldImage - * @see \PHPThumb\GD::$oldImage - */ - public function setOldImage($oldImage) - { - $this->oldImage = $oldImage; - - return $this; - } - - /** - * Returns $workingImage. - * - * @see \PHPThumb\GD::$workingImage - */ - public function getWorkingImage() - { - return $this->workingImage; - } - - /** - * Sets $workingImage. - * - * @param object $workingImage - * @see \PHPThumb\GD::$workingImage - */ - public function setWorkingImage($workingImage) - { - $this->workingImage = $workingImage; - - return $this; - } - - - ################################# - # ----- UTILITY FUNCTIONS ----- # - ################################# - - /** - * Calculates a new width and height for the image based on $this->maxWidth and the provided dimensions - * - * @return array - * @param int $width - * @param int $height - */ - protected function calcWidth($width, $height) - { - $newWidthPercentage = (100 * $this->maxWidth) / $width; - $newHeight = ($height * $newWidthPercentage) / 100; - - return array( - 'newWidth' => intval($this->maxWidth), - 'newHeight' => intval($newHeight) - ); - } - - /** - * Calculates a new width and height for the image based on $this->maxWidth and the provided dimensions - * - * @return array - * @param int $width - * @param int $height - */ - protected function calcHeight($width, $height) - { - $newHeightPercentage = (100 * $this->maxHeight) / $height; - $newWidth = ($width * $newHeightPercentage) / 100; - - return array( - 'newWidth' => ceil($newWidth), - 'newHeight' => ceil($this->maxHeight) - ); - } - - /** - * Calculates a new width and height for the image based on $this->percent and the provided dimensions - * - * @return array - * @param int $width - * @param int $height - */ - protected function calcPercent($width, $height) - { - $newWidth = ($width * $this->percent) / 100; - $newHeight = ($height * $this->percent) / 100; - - return array( - 'newWidth' => ceil($newWidth), - 'newHeight' => ceil($newHeight) - ); - } - - /** - * Calculates the new image dimensions - * - * These calculations are based on both the provided dimensions and $this->maxWidth and $this->maxHeight - * - * @param int $width - * @param int $height - */ - protected function calcImageSize($width, $height) - { - $newSize = array( - 'newWidth' => $width, - 'newHeight' => $height - ); - - if ($this->maxWidth > 0) { - $newSize = $this->calcWidth($width, $height); - - if ($this->maxHeight > 0 && $newSize['newHeight'] > $this->maxHeight) { - $newSize = $this->calcHeight($newSize['newWidth'], $newSize['newHeight']); - } - } - - if ($this->maxHeight > 0) { - $newSize = $this->calcHeight($width, $height); - - if ($this->maxWidth > 0 && $newSize['newWidth'] > $this->maxWidth) { - $newSize = $this->calcWidth($newSize['newWidth'], $newSize['newHeight']); - } - } - - $this->newDimensions = $newSize; - } - - /** - * Calculates new image dimensions, not allowing the width and height to be less than either the max width or height - * - * @param int $width - * @param int $height - */ - protected function calcImageSizeStrict($width, $height) - { - // first, we need to determine what the longest resize dimension is.. - if ($this->maxWidth >= $this->maxHeight) { - // and determine the longest original dimension - if ($width > $height) { - $newDimensions = $this->calcHeight($width, $height); - - if ($newDimensions['newWidth'] < $this->maxWidth) { - $newDimensions = $this->calcWidth($width, $height); - } - } elseif ($height >= $width) { - $newDimensions = $this->calcWidth($width, $height); - - if ($newDimensions['newHeight'] < $this->maxHeight) { - $newDimensions = $this->calcHeight($width, $height); - } - } - } elseif ($this->maxHeight > $this->maxWidth) { - if ($width >= $height) { - $newDimensions = $this->calcWidth($width, $height); - - if ($newDimensions['newHeight'] < $this->maxHeight) { - $newDimensions = $this->calcHeight($width, $height); - } - } elseif ($height > $width) { - $newDimensions = $this->calcHeight($width, $height); - - if ($newDimensions['newWidth'] < $this->maxWidth) { - $newDimensions = $this->calcWidth($width, $height); - } - } - } - - $this->newDimensions = $newDimensions; - } - - /** - * Calculates new dimensions based on $this->percent and the provided dimensions - * - * @param int $width - * @param int $height - */ - protected function calcImageSizePercent($width, $height) - { - if ($this->percent > 0) { - $this->newDimensions = $this->calcPercent($width, $height); - } - } - - /** - * Determines the file format by mime-type - * - * This function will throw exceptions for invalid images / mime-types - * - */ - protected function determineFormat() - { - $formatInfo = getimagesize($this->fileName); - - // non-image files will return false - if ($formatInfo === false) { - if ($this->remoteImage) { - throw new \Exception("Could not determine format of remote image: {$this->fileName}"); - } else { - throw new \Exception("File is not a valid image: {$this->fileName}"); - } - } - - $mimeType = isset($formatInfo['mime']) ? $formatInfo['mime'] : null; - - switch ($mimeType) { - case 'image/gif': - $this->format = 'GIF'; - break; - case 'image/jpeg': - $this->format = 'JPG'; - break; - case 'image/png': - $this->format = 'PNG'; - break; - default: - throw new \Exception("Image format not supported: {$mimeType}"); - } - } - - /** - * Makes sure the correct GD implementation exists for the file type - * - */ - protected function verifyFormatCompatiblity() - { - $isCompatible = true; - $gdInfo = gd_info(); - - switch ($this->format) { - case 'GIF': - $isCompatible = isset($gdInfo['GIF Create Support']); - break; - case 'JPG': - $isCompatible = (isset($gdInfo['JPG Support']) || isset($gdInfo['JPEG Support'])) ? true : false; - break; - case 'PNG': - $isCompatible = isset($gdInfo[$this->format . ' Support']); - break; - default: - $isCompatible = false; - } - - if (!$isCompatible) { - // one last check for "JPEG" instead - $isCompatible = isset($gdInfo['JPEG Support']); - - if (!$isCompatible) { - throw new \Exception("Your GD installation does not support {$this->format} image types"); - } - } - } - - /** - * Preserves the alpha or transparency for PNG and GIF files - * - * Alpha / transparency will not be preserved if the appropriate options are set to false. - * Also, the GIF transparency is pretty skunky (the results aren't awesome), but it works like a - * champ... that's the nature of GIFs tho, so no huge surprise. - * - * This functionality was originally suggested by commenter Aimi (no links / site provided) - Thanks! :) - * - */ - protected function preserveAlpha() - { - if ($this->format == 'PNG' && $this->options['preserveAlpha'] === true) { - imagealphablending($this->workingImage, false); - - $colorTransparent = imagecolorallocatealpha( - $this->workingImage, - $this->options['alphaMaskColor'][0], - $this->options['alphaMaskColor'][1], - $this->options['alphaMaskColor'][2], - 0 - ); - - imagefill($this->workingImage, 0, 0, $colorTransparent); - imagesavealpha($this->workingImage, true); - } - // preserve transparency in GIFs... this is usually pretty rough tho - if ($this->format == 'GIF' && $this->options['preserveTransparency'] === true) { - $colorTransparent = imagecolorallocate( - $this->workingImage, - $this->options['transparencyMaskColor'][0], - $this->options['transparencyMaskColor'][1], - $this->options['transparencyMaskColor'][2] - ); - - imagecolortransparent($this->workingImage, $colorTransparent); - imagetruecolortopalette($this->workingImage, true, 256); - } - } -} + + * Copyright (c) 2009, Ian Selby/Gen X Design + * + * Author(s): Ian Selby + * + * Licensed under the MIT License + * Redistributions of files must retain the above copyright notice. + * + * @author Ian Selby + * @copyright Copyright (c) 2009 Gen X Design + * @link http://phpthumb.gxdlabs.com + * @license http://www.opensource.org/licenses/mit-license.php The MIT License + */ + +class GD extends PHPThumb +{ + /** + * The prior image (before manipulation) + * + * @var resource + */ + protected $oldImage; + + /** + * The working image (used during manipulation) + * + * @var resource + */ + protected $workingImage; + + /** + * The current dimensions of the image + * + * @var array + */ + protected $currentDimensions; + + /** + * The new, calculated dimensions of the image + * + * @var array + */ + protected $newDimensions; + + /** + * The options for this class + * + * This array contains various options that determine the behavior in + * various functions throughout the class. Functions note which specific + * option key / values are used in their documentation + * + * @var array + */ + protected $options; + + /** + * The maximum width an image can be after resizing (in pixels) + * + * @var int + */ + protected $maxWidth; + + /** + * The maximum height an image can be after resizing (in pixels) + * + * @var int + */ + protected $maxHeight; + + /** + * The percentage to resize the image by + * + * @var int + */ + protected $percent; + + /** + * @param string $fileName + * @param array $options + * @param array $plugins + */ + public function __construct($fileName, $options = array(), array $plugins = array()) + { + parent::__construct($fileName, $options, $plugins); + + $this->determineFormat(); + $this->verifyFormatCompatiblity(); + + switch ($this->format) { + case 'GIF': + $this->oldImage = @imagecreatefromgif($this->fileName); + break; + case 'JPG': + $this->oldImage = @imagecreatefromjpeg($this->fileName); + break; + case 'PNG': + $this->oldImage = @imagecreatefrompng($this->fileName); + break; + case 'STRING': + $this->oldImage = @imagecreatefromstring($this->fileName); + break; + } + + if (!is_resource($this->oldImage)) + { + throw new \Exception('Invalid image file'); + } + else + { + $this->currentDimensions = array ( + 'width' => imagesx($this->oldImage), + 'height' => imagesy($this->oldImage) + ); + } + } + + public function __destruct() + { + if (is_resource($this->oldImage)) { + imagedestroy($this->oldImage); + } + + if (is_resource($this->workingImage)) { + imagedestroy($this->workingImage); + } + } + + /** + * Pad an image to desired dimensions. Moves the image into the center and fills the rest with $color. + * @param $width + * @param $height + * @param array $color + * @return GD + */ + public function pad($width, $height, $color = array(255, 255, 255)) + { + // no resize - woohoo! + if ($width == $this->currentDimensions['width'] && $height == $this->currentDimensions['height']) { + return $this; + } + + // create the working image + if (function_exists('imagecreatetruecolor')) { + $this->workingImage = imagecreatetruecolor($width, $height); + } else { + $this->workingImage = imagecreate($width, $height); + } + + // create the fill color + $fillColor = imagecolorallocate( + $this->workingImage, + $color[0], + $color[1], + $color[2] + ); + + // fill our working image with the fill color + imagefill( + $this->workingImage, + 0, + 0, + $fillColor + ); + + // copy the image into the center of our working image + imagecopyresampled( + $this->workingImage, + $this->oldImage, + intval(($width-$this->currentDimensions['width']) / 2), + intval(($height-$this->currentDimensions['height']) / 2), + 0, + 0, + $this->currentDimensions['width'], + $this->currentDimensions['height'], + $this->currentDimensions['width'], + $this->currentDimensions['height'] + ); + + // update all the variables and resources to be correct + $this->oldImage = $this->workingImage; + $this->currentDimensions['width'] = $width; + $this->currentDimensions['height'] = $height; + + return $this; + } + + /** + * Resizes an image to be no larger than $maxWidth or $maxHeight + * + * If either param is set to zero, then that dimension will not be considered as a part of the resize. + * Additionally, if $this->options['resizeUp'] is set to true (false by default), then this function will + * also scale the image up to the maximum dimensions provided. + * + * @param int $maxWidth The maximum width of the image in pixels + * @param int $maxHeight The maximum height of the image in pixels + * @return \PHPThumb\GD + */ + public function resize($maxWidth = 0, $maxHeight = 0) + { + // make sure our arguments are valid + if (!is_numeric($maxWidth)) { + throw new \InvalidArgumentException('$maxWidth must be numeric'); + } + + if (!is_numeric($maxHeight)) { + throw new \InvalidArgumentException('$maxHeight must be numeric'); + } + + // make sure we're not exceeding our image size if we're not supposed to + if ($this->options['resizeUp'] === false) { + $this->maxHeight = (intval($maxHeight) > $this->currentDimensions['height']) ? $this->currentDimensions['height'] : $maxHeight; + $this->maxWidth = (intval($maxWidth) > $this->currentDimensions['width']) ? $this->currentDimensions['width'] : $maxWidth; + } else { + $this->maxHeight = intval($maxHeight); + $this->maxWidth = intval($maxWidth); + } + + // get the new dimensions... + $this->calcImageSize($this->currentDimensions['width'], $this->currentDimensions['height']); + + // create the working image + if (function_exists('imagecreatetruecolor')) { + $this->workingImage = imagecreatetruecolor($this->newDimensions['newWidth'], $this->newDimensions['newHeight']); + } else { + $this->workingImage = imagecreate($this->newDimensions['newWidth'], $this->newDimensions['newHeight']); + } + + $this->preserveAlpha(); + + // and create the newly sized image + imagecopyresampled( + $this->workingImage, + $this->oldImage, + 0, + 0, + 0, + 0, + $this->newDimensions['newWidth'], + $this->newDimensions['newHeight'], + $this->currentDimensions['width'], + $this->currentDimensions['height'] + ); + + // update all the variables and resources to be correct + $this->oldImage = $this->workingImage; + $this->currentDimensions['width'] = $this->newDimensions['newWidth']; + $this->currentDimensions['height'] = $this->newDimensions['newHeight']; + + return $this; + } + + /** + * Adaptively Resizes the Image + * + * This function attempts to get the image to as close to the provided dimensions as possible, and then crops the + * remaining overflow (from the center) to get the image to be the size specified + * + * @param int $maxWidth + * @param int $maxHeight + * @return \PHPThumb\GD + */ + public function adaptiveResize($width, $height) + { + // make sure our arguments are valid + if ((!is_numeric($width) || $width == 0) && (!is_numeric($height) || $height == 0)) { + throw new \InvalidArgumentException('$width and $height must be numeric and greater than zero'); + } + + if (!is_numeric($width) || $width == 0) { + $width = ($height * $this->currentDimensions['width']) / $this->currentDimensions['height']; + } + + if (!is_numeric($height) || $height == 0) { + $height = ($width * $this->currentDimensions['height']) / $this->currentDimensions['width']; + } + + // make sure we're not exceeding our image size if we're not supposed to + if ($this->options['resizeUp'] === false) { + $this->maxHeight = (intval($height) > $this->currentDimensions['height']) ? $this->currentDimensions['height'] : $height; + $this->maxWidth = (intval($width) > $this->currentDimensions['width']) ? $this->currentDimensions['width'] : $width; + } else { + $this->maxHeight = intval($height); + $this->maxWidth = intval($width); + } + + $this->calcImageSizeStrict($this->currentDimensions['width'], $this->currentDimensions['height']); + + // resize the image to be close to our desired dimensions + $this->resize($this->newDimensions['newWidth'], $this->newDimensions['newHeight']); + + // reset the max dimensions... + if ($this->options['resizeUp'] === false) { + $this->maxHeight = (intval($height) > $this->currentDimensions['height']) ? $this->currentDimensions['height'] : $height; + $this->maxWidth = (intval($width) > $this->currentDimensions['width']) ? $this->currentDimensions['width'] : $width; + } else { + $this->maxHeight = intval($height); + $this->maxWidth = intval($width); + } + + // create the working image + if (function_exists('imagecreatetruecolor')) { + $this->workingImage = imagecreatetruecolor($this->maxWidth, $this->maxHeight); + } else { + $this->workingImage = imagecreate($this->maxWidth, $this->maxHeight); + } + + $this->preserveAlpha(); + + $cropWidth = $this->maxWidth; + $cropHeight = $this->maxHeight; + $cropX = 0; + $cropY = 0; + + // now, figure out how to crop the rest of the image... + if ($this->currentDimensions['width'] > $this->maxWidth) { + $cropX = intval(($this->currentDimensions['width'] - $this->maxWidth) / 2); + } elseif ($this->currentDimensions['height'] > $this->maxHeight) { + $cropY = intval(($this->currentDimensions['height'] - $this->maxHeight) / 2); + } + + imagecopyresampled( + $this->workingImage, + $this->oldImage, + 0, + 0, + $cropX, + $cropY, + $cropWidth, + $cropHeight, + $cropWidth, + $cropHeight + ); + + // update all the variables and resources to be correct + $this->oldImage = $this->workingImage; + $this->currentDimensions['width'] = $this->maxWidth; + $this->currentDimensions['height'] = $this->maxHeight; + + return $this; + } + + /** + * Adaptively Resizes the Image and Crops Using a Percentage + * + * This function attempts to get the image to as close to the provided dimensions as possible, and then crops the + * remaining overflow using a provided percentage to get the image to be the size specified. + * + * The percentage mean different things depending on the orientation of the original image. + * + * For Landscape images: + * --------------------- + * + * A percentage of 1 would crop the image all the way to the left, which would be the same as + * using adaptiveResizeQuadrant() with $quadrant = 'L' + * + * A percentage of 50 would crop the image to the center which would be the same as using + * adaptiveResizeQuadrant() with $quadrant = 'C', or even the original adaptiveResize() + * + * A percentage of 100 would crop the image to the image all the way to the right, etc, etc. + * Note that you can use any percentage between 1 and 100. + * + * For Portrait images: + * -------------------- + * + * This works the same as for Landscape images except that a percentage of 1 means top and 100 means bottom + * + * @param int $maxWidth + * @param int $maxHeight + * @param int $percent + * @return \PHPThumb\GD + */ + public function adaptiveResizePercent($width, $height, $percent = 50) + { + // make sure our arguments are valid + if (!is_numeric($width) || $width == 0) { + throw new \InvalidArgumentException('$width must be numeric and greater than zero'); + } + + if (!is_numeric($height) || $height == 0) { + throw new \InvalidArgumentException('$height must be numeric and greater than zero'); + } + + // make sure we're not exceeding our image size if we're not supposed to + if ($this->options['resizeUp'] === false) { + $this->maxHeight = (intval($height) > $this->currentDimensions['height']) ? $this->currentDimensions['height'] : $height; + $this->maxWidth = (intval($width) > $this->currentDimensions['width']) ? $this->currentDimensions['width'] : $width; + } else { + $this->maxHeight = intval($height); + $this->maxWidth = intval($width); + } + + $this->calcImageSizeStrict($this->currentDimensions['width'], $this->currentDimensions['height']); + + // resize the image to be close to our desired dimensions + $this->resize($this->newDimensions['newWidth'], $this->newDimensions['newHeight']); + + // reset the max dimensions... + if ($this->options['resizeUp'] === false) { + $this->maxHeight = (intval($height) > $this->currentDimensions['height']) ? $this->currentDimensions['height'] : $height; + $this->maxWidth = (intval($width) > $this->currentDimensions['width']) ? $this->currentDimensions['width'] : $width; + } else { + $this->maxHeight = intval($height); + $this->maxWidth = intval($width); + } + + // create the working image + if (function_exists('imagecreatetruecolor')) { + $this->workingImage = imagecreatetruecolor($this->maxWidth, $this->maxHeight); + } else { + $this->workingImage = imagecreate($this->maxWidth, $this->maxHeight); + } + + $this->preserveAlpha(); + + $cropWidth = $this->maxWidth; + $cropHeight = $this->maxHeight; + $cropX = 0; + $cropY = 0; + + // Crop the rest of the image using the quadrant + + if ($percent > 100) { + $percent = 100; + } elseif ($percent < 1) { + $percent = 1; + } + + if ($this->currentDimensions['width'] > $this->maxWidth) { + // Image is landscape + $maxCropX = $this->currentDimensions['width'] - $this->maxWidth; + $cropX = intval(($percent / 100) * $maxCropX); + + } elseif ($this->currentDimensions['height'] > $this->maxHeight) { + // Image is portrait + $maxCropY = $this->currentDimensions['height'] - $this->maxHeight; + $cropY = intval(($percent / 100) * $maxCropY); + } + + imagecopyresampled( + $this->workingImage, + $this->oldImage, + 0, + 0, + $cropX, + $cropY, + $cropWidth, + $cropHeight, + $cropWidth, + $cropHeight + ); + + // update all the variables and resources to be correct + $this->oldImage = $this->workingImage; + $this->currentDimensions['width'] = $this->maxWidth; + $this->currentDimensions['height'] = $this->maxHeight; + + return $this; + } + + /** + * Adaptively Resizes the Image and Crops Using a Quadrant + * + * This function attempts to get the image to as close to the provided dimensions as possible, and then crops the + * remaining overflow using the quadrant to get the image to be the size specified. + * + * The quadrants available are Top, Bottom, Center, Left, and Right: + * + * + * +---+---+---+ + * | | T | | + * +---+---+---+ + * | L | C | R | + * +---+---+---+ + * | | B | | + * +---+---+---+ + * + * Note that if your image is Landscape and you choose either of the Top or Bottom quadrants (which won't + * make sence since only the Left and Right would be available, then the Center quadrant will be used + * to crop. This would have exactly the same result as using adaptiveResize(). + * The same goes if your image is portrait and you choose either the Left or Right quadrants. + * + * @param int $maxWidth + * @param int $maxHeight + * @param string $quadrant T, B, C, L, R + * @return \PHPThumb\GD + */ + public function adaptiveResizeQuadrant($width, $height, $quadrant = 'C') + { + // make sure our arguments are valid + if (!is_numeric($width) || $width == 0) { + throw new \InvalidArgumentException('$width must be numeric and greater than zero'); + } + + if (!is_numeric($height) || $height == 0) { + throw new \InvalidArgumentException('$height must be numeric and greater than zero'); + } + + // make sure we're not exceeding our image size if we're not supposed to + if ($this->options['resizeUp'] === false) { + $this->maxHeight = (intval($height) > $this->currentDimensions['height']) ? $this->currentDimensions['height'] : $height; + $this->maxWidth = (intval($width) > $this->currentDimensions['width']) ? $this->currentDimensions['width'] : $width; + } else { + $this->maxHeight = intval($height); + $this->maxWidth = intval($width); + } + + $this->calcImageSizeStrict($this->currentDimensions['width'], $this->currentDimensions['height']); + + // resize the image to be close to our desired dimensions + $this->resize($this->newDimensions['newWidth'], $this->newDimensions['newHeight']); + + // reset the max dimensions... + if ($this->options['resizeUp'] === false) { + $this->maxHeight = (intval($height) > $this->currentDimensions['height']) ? $this->currentDimensions['height'] : $height; + $this->maxWidth = (intval($width) > $this->currentDimensions['width']) ? $this->currentDimensions['width'] : $width; + } else { + $this->maxHeight = intval($height); + $this->maxWidth = intval($width); + } + + // create the working image + if (function_exists('imagecreatetruecolor')) { + $this->workingImage = imagecreatetruecolor($this->maxWidth, $this->maxHeight); + } else { + $this->workingImage = imagecreate($this->maxWidth, $this->maxHeight); + } + + $this->preserveAlpha(); + + $cropWidth = $this->maxWidth; + $cropHeight = $this->maxHeight; + $cropX = 0; + $cropY = 0; + + // Crop the rest of the image using the quadrant + + if ($this->currentDimensions['width'] > $this->maxWidth) { + // Image is landscape + switch ($quadrant) { + case 'L': + $cropX = 0; + break; + case 'R': + $cropX = intval(($this->currentDimensions['width'] - $this->maxWidth)); + break; + case 'C': + default: + $cropX = intval(($this->currentDimensions['width'] - $this->maxWidth) / 2); + break; + } + } elseif ($this->currentDimensions['height'] > $this->maxHeight) { + // Image is portrait + switch ($quadrant) { + case 'T': + $cropY = 0; + break; + case 'B': + $cropY = intval(($this->currentDimensions['height'] - $this->maxHeight)); + break; + case 'C': + default: + $cropY = intval(($this->currentDimensions['height'] - $this->maxHeight) / 2); + break; + } + } + + imagecopyresampled( + $this->workingImage, + $this->oldImage, + 0, + 0, + $cropX, + $cropY, + $cropWidth, + $cropHeight, + $cropWidth, + $cropHeight + ); + + // update all the variables and resources to be correct + $this->oldImage = $this->workingImage; + $this->currentDimensions['width'] = $this->maxWidth; + $this->currentDimensions['height'] = $this->maxHeight; + + return $this; + } + + /** + * Resizes an image by a given percent uniformly, + * Percentage should be whole number representation (i.e. 1-100) + * + * @param int $percent + * @return GD + * @throws \InvalidArgumentException + */ + public function resizePercent($percent = 0) + { + if (!is_numeric($percent)) { + throw new \InvalidArgumentException ('$percent must be numeric'); + } + + $this->percent = intval($percent); + + $this->calcImageSizePercent($this->currentDimensions['width'], $this->currentDimensions['height']); + + if (function_exists('imagecreatetruecolor')) { + $this->workingImage = imagecreatetruecolor($this->newDimensions['newWidth'], $this->newDimensions['newHeight']); + } else { + $this->workingImage = imagecreate($this->newDimensions['newWidth'], $this->newDimensions['newHeight']); + } + + $this->preserveAlpha(); + + imagecopyresampled( + $this->workingImage, + $this->oldImage, + 0, + 0, + 0, + 0, + $this->newDimensions['newWidth'], + $this->newDimensions['newHeight'], + $this->currentDimensions['width'], + $this->currentDimensions['height'] + ); + + $this->oldImage = $this->workingImage; + $this->currentDimensions['width'] = $this->newDimensions['newWidth']; + $this->currentDimensions['height'] = $this->newDimensions['newHeight']; + + return $this; + } + + /** + * Crops an image from the center with provided dimensions + * + * If no height is given, the width will be used as a height, thus creating a square crop + * + * @param int $cropWidth + * @param int $cropHeight + * @return \PHPThumb\GD + */ + public function cropFromCenter($cropWidth, $cropHeight = null) + { + if (!is_numeric($cropWidth)) { + throw new \InvalidArgumentException('$cropWidth must be numeric'); + } + + if ($cropHeight !== null && !is_numeric($cropHeight)) { + throw new \InvalidArgumentException('$cropHeight must be numeric'); + } + + if ($cropHeight === null) { + $cropHeight = $cropWidth; + } + + $cropWidth = ($this->currentDimensions['width'] < $cropWidth) ? $this->currentDimensions['width'] : $cropWidth; + $cropHeight = ($this->currentDimensions['height'] < $cropHeight) ? $this->currentDimensions['height'] : $cropHeight; + + $cropX = intval(($this->currentDimensions['width'] - $cropWidth) / 2); + $cropY = intval(($this->currentDimensions['height'] - $cropHeight) / 2); + + $this->crop($cropX, $cropY, $cropWidth, $cropHeight); + + return $this; + } + + /** + * Vanilla Cropping - Crops from x,y with specified width and height + * + * @param int $startX + * @param int $startY + * @param int $cropWidth + * @param int $cropHeight + * @return \PHPThumb\GD + */ + public function crop($startX, $startY, $cropWidth, $cropHeight) + { + // validate input + if (!is_numeric($startX)) { + throw new \InvalidArgumentException('$startX must be numeric'); + } + + if (!is_numeric($startY)) { + throw new \InvalidArgumentException('$startY must be numeric'); + } + + if (!is_numeric($cropWidth)) { + throw new \InvalidArgumentException('$cropWidth must be numeric'); + } + + if (!is_numeric($cropHeight)) { + throw new \InvalidArgumentException('$cropHeight must be numeric'); + } + + // do some calculations + $cropWidth = ($this->currentDimensions['width'] < $cropWidth) ? $this->currentDimensions['width'] : $cropWidth; + $cropHeight = ($this->currentDimensions['height'] < $cropHeight) ? $this->currentDimensions['height'] : $cropHeight; + + // ensure everything's in bounds + if (($startX + $cropWidth) > $this->currentDimensions['width']) { + $startX = ($this->currentDimensions['width'] - $cropWidth); + } + + if (($startY + $cropHeight) > $this->currentDimensions['height']) { + $startY = ($this->currentDimensions['height'] - $cropHeight); + } + + if ($startX < 0) { + $startX = 0; + } + + if ($startY < 0) { + $startY = 0; + } + + // create the working image + if (function_exists('imagecreatetruecolor')) { + $this->workingImage = imagecreatetruecolor($cropWidth, $cropHeight); + } else { + $this->workingImage = imagecreate($cropWidth, $cropHeight); + } + + $this->preserveAlpha(); + + imagecopyresampled( + $this->workingImage, + $this->oldImage, + 0, + 0, + $startX, + $startY, + $cropWidth, + $cropHeight, + $cropWidth, + $cropHeight + ); + + $this->oldImage = $this->workingImage; + $this->currentDimensions['width'] = $cropWidth; + $this->currentDimensions['height'] = $cropHeight; + + return $this; + } + + /** + * Rotates image either 90 degrees clockwise or counter-clockwise + * + * @param string $direction + * @retunrn \PHPThumb\GD + */ + public function rotateImage($direction = 'CW') + { + if ($direction == 'CW') { + $this->rotateImageNDegrees(90); + } else { + $this->rotateImageNDegrees(-90); + } + + return $this; + } + + /** + * Rotates image specified number of degrees + * + * @param int $degrees + * @return \PHPThumb\GD + */ + public function rotateImageNDegrees($degrees) + { + if (!is_numeric($degrees)) { + throw new \InvalidArgumentException('$degrees must be numeric'); + } + + if (!function_exists('imagerotate')) { + throw new \RuntimeException('Your version of GD does not support image rotation'); + } + + $this->workingImage = imagerotate($this->oldImage, $degrees, 0); + + $newWidth = $this->currentDimensions['height']; + $newHeight = $this->currentDimensions['width']; + $this->oldImage = $this->workingImage; + $this->currentDimensions['width'] = $newWidth; + $this->currentDimensions['height'] = $newHeight; + + return $this; + } + + /** + * Applies a filter to the image + * + * @param int $filter + * @return \PHPThumb\GD + */ + public function imageFilter($filter, $arg1 = false, $arg2 = false, $arg3 = false, $arg4 = false) + { + if (!is_numeric($filter)) { + throw new \InvalidArgumentException('$filter must be numeric'); + } + + if (!function_exists('imagefilter')) { + throw new \RuntimeException('Your version of GD does not support image filters'); + } + + $result = false; + if ($arg1 === false) { + $result = imagefilter($this->oldImage, $filter); + } elseif ($arg2 === false) { + $result = imagefilter($this->oldImage, $filter, $arg1); + } elseif ($arg3 === false) { + $result = imagefilter($this->oldImage, $filter, $arg1, $arg2); + } elseif ($arg4 === false) { + $result = imagefilter($this->oldImage, $filter, $arg1, $arg2, $arg3); + } else { + $result = imagefilter($this->oldImage, $filter, $arg1, $arg2, $arg3, $arg4); + } + + if (!$result) { + throw new \RuntimeException('GD imagefilter failed'); + } + + $this->workingImage = $this->oldImage; + + return $this; + } + + /** + * Shows an image + * + * This function will show the current image by first sending the appropriate header + * for the format, and then outputting the image data. If headers have already been sent, + * a runtime exception will be thrown + * + * @param bool $rawData Whether or not the raw image stream should be output + * @return \PHPThumb\GD + */ + public function show($rawData = false) + { + //Execute any plugins + if ($this->plugins) { + foreach ($this->plugins as $plugin) { + /* @var $plugin \PHPThumb\PluginInterface */ + $plugin->execute($this); + } + } + + if (headers_sent() && php_sapi_name() != 'cli') { + throw new \RuntimeException('Cannot show image, headers have already been sent'); + } + + // When the interlace option equals true or false call imageinterlace else leave it to default + if ($this->options['interlace'] === true) { + imageinterlace($this->oldImage, 1); + } elseif ($this->options['interlace'] === false) { + imageinterlace($this->oldImage, 0); + } + + switch ($this->format) { + case 'GIF': + if ($rawData === false) { + header('Content-type: image/gif'); + } + imagegif($this->oldImage); + break; + case 'JPG': + if ($rawData === false) { + header('Content-type: image/jpeg'); + } + imagejpeg($this->oldImage, null, $this->options['jpegQuality']); + break; + case 'PNG': + case 'STRING': + if ($rawData === false) { + header('Content-type: image/png'); + } + imagepng($this->oldImage); + break; + } + + return $this; + } + + /** + * Returns the Working Image as a String + * + * This function is useful for getting the raw image data as a string for storage in + * a database, or other similar things. + * + * @return string + */ + public function getImageAsString() + { + $data = null; + ob_start(); + $this->show(true); + $data = ob_get_contents(); + ob_end_clean(); + + return $data; + } + + /** + * Saves an image + * + * This function will make sure the target directory is writeable, and then save the image. + * + * If the target directory is not writeable, the function will try to correct the permissions (if allowed, this + * is set as an option ($this->options['correctPermissions']). If the target cannot be made writeable, then a + * \RuntimeException is thrown. + * + * @param string $fileName The full path and filename of the image to save + * @param string $format The format to save the image in (optional, must be one of [GIF,JPG,PNG] + * @return \PHPThumb\GD + */ + public function save($fileName, $format = null) + { + $validFormats = array('GIF', 'JPG', 'PNG'); + $format = ($format !== null) ? strtoupper($format) : $this->format; + + if (!in_array($format, $validFormats)) { + throw new \InvalidArgumentException("Invalid format type specified in save function: {$format}"); + } + + // make sure the directory is writeable + if (!is_writeable(dirname($fileName))) { + // try to correct the permissions + if ($this->options['correctPermissions'] === true) { + @chmod(dirname($fileName), 0777); + + // throw an exception if not writeable + if (!is_writeable(dirname($fileName))) { + throw new \RuntimeException("File is not writeable, and could not correct permissions: {$fileName}"); + } + } else { // throw an exception if not writeable + throw new \RuntimeException("File not writeable: {$fileName}"); + } + } + + // When the interlace option equals true or false call imageinterlace else leave it to default + if ($this->options['interlace'] === true) { + imageinterlace($this->oldImage, 1); + } elseif ($this->options['interlace'] === false) { + imageinterlace($this->oldImage, 0); + } + + switch ($format) { + case 'GIF': + imagegif($this->oldImage, $fileName); + break; + case 'JPG': + imagejpeg($this->oldImage, $fileName, $this->options['jpegQuality']); + break; + case 'PNG': + imagepng($this->oldImage, $fileName); + break; + } + + return $this; + } + + ################################# + # ----- GETTERS / SETTERS ----- # + ################################# + + /** + * Sets options for all operations. + * @param array $options + * @return GD + */ + public function setOptions(array $options = array()) + { + // we've yet to init the default options, so create them here + if (sizeof($this->options) == 0) { + $defaultOptions = array( + 'resizeUp' => false, + 'jpegQuality' => 100, + 'correctPermissions' => false, + 'preserveAlpha' => true, + 'alphaMaskColor' => array (255, 255, 255), + 'preserveTransparency' => true, + 'transparencyMaskColor' => array (0, 0, 0), + 'interlace' => null + ); + } else { // otherwise, let's use what we've got already + $defaultOptions = $this->options; + } + + $this->options = array_merge($defaultOptions, $options); + + return $this; + } + + /** + * Returns $currentDimensions. + * + * @see \PHPThumb\GD::$currentDimensions + */ + public function getCurrentDimensions() + { + return $this->currentDimensions; + } + + /** + * @param $currentDimensions + * @return GD + */ + public function setCurrentDimensions($currentDimensions) + { + $this->currentDimensions = $currentDimensions; + + return $this; + } + + /** + * @return int + */ + public function getMaxHeight() + { + return $this->maxHeight; + } + + /** + * @param $maxHeight + * @return GD + */ + public function setMaxHeight($maxHeight) + { + $this->maxHeight = $maxHeight; + + return $this; + } + + /** + * @return int + */ + public function getMaxWidth() + { + return $this->maxWidth; + } + + /** + * @param $maxWidth + * @return GD + */ + public function setMaxWidth($maxWidth) + { + $this->maxWidth = $maxWidth; + + return $this; + } + + /** + * Returns $newDimensions. + * + * @see \PHPThumb\GD::$newDimensions + */ + public function getNewDimensions() + { + return $this->newDimensions; + } + + /** + * Sets $newDimensions. + * + * @param object $newDimensions + * @see \PHPThumb\GD::$newDimensions + */ + public function setNewDimensions($newDimensions) + { + $this->newDimensions = $newDimensions; + + return $this; + } + + /** + * Returns $options. + * + * @see \PHPThumb\GD::$options + */ + public function getOptions() + { + return $this->options; + } + + /** + * Returns $percent. + * + * @see \PHPThumb\GD::$percent + */ + public function getPercent() + { + return $this->percent; + } + + /** + * Sets $percent. + * + * @param object $percent + * @see \PHPThumb\GD::$percent + */ + public function setPercent($percent) + { + $this->percent = $percent; + + return $this; + } + + /** + * Returns $oldImage. + * + * @see \PHPThumb\GD::$oldImage + */ + public function getOldImage() + { + return $this->oldImage; + } + + /** + * Sets $oldImage. + * + * @param object $oldImage + * @see \PHPThumb\GD::$oldImage + */ + public function setOldImage($oldImage) + { + $this->oldImage = $oldImage; + + return $this; + } + + /** + * Returns $workingImage. + * + * @see \PHPThumb\GD::$workingImage + */ + public function getWorkingImage() + { + return $this->workingImage; + } + + /** + * Sets $workingImage. + * + * @param object $workingImage + * @see \PHPThumb\GD::$workingImage + */ + public function setWorkingImage($workingImage) + { + $this->workingImage = $workingImage; + + return $this; + } + + + ################################# + # ----- UTILITY FUNCTIONS ----- # + ################################# + + /** + * Calculates a new width and height for the image based on $this->maxWidth and the provided dimensions + * + * @return array + * @param int $width + * @param int $height + */ + protected function calcWidth($width, $height) + { + $newWidthPercentage = (100 * $this->maxWidth) / $width; + $newHeight = ($height * $newWidthPercentage) / 100; + + return array( + 'newWidth' => intval($this->maxWidth), + 'newHeight' => intval($newHeight) + ); + } + + /** + * Calculates a new width and height for the image based on $this->maxWidth and the provided dimensions + * + * @return array + * @param int $width + * @param int $height + */ + protected function calcHeight($width, $height) + { + $newHeightPercentage = (100 * $this->maxHeight) / $height; + $newWidth = ($width * $newHeightPercentage) / 100; + + return array( + 'newWidth' => ceil($newWidth), + 'newHeight' => ceil($this->maxHeight) + ); + } + + /** + * Calculates a new width and height for the image based on $this->percent and the provided dimensions + * + * @return array + * @param int $width + * @param int $height + */ + protected function calcPercent($width, $height) + { + $newWidth = ($width * $this->percent) / 100; + $newHeight = ($height * $this->percent) / 100; + + return array( + 'newWidth' => ceil($newWidth), + 'newHeight' => ceil($newHeight) + ); + } + + /** + * Calculates the new image dimensions + * + * These calculations are based on both the provided dimensions and $this->maxWidth and $this->maxHeight + * + * @param int $width + * @param int $height + */ + protected function calcImageSize($width, $height) + { + $newSize = array( + 'newWidth' => $width, + 'newHeight' => $height + ); + + if ($this->maxWidth > 0) { + $newSize = $this->calcWidth($width, $height); + + if ($this->maxHeight > 0 && $newSize['newHeight'] > $this->maxHeight) { + $newSize = $this->calcHeight($newSize['newWidth'], $newSize['newHeight']); + } + } + + if ($this->maxHeight > 0) { + $newSize = $this->calcHeight($width, $height); + + if ($this->maxWidth > 0 && $newSize['newWidth'] > $this->maxWidth) { + $newSize = $this->calcWidth($newSize['newWidth'], $newSize['newHeight']); + } + } + + $this->newDimensions = $newSize; + } + + /** + * Calculates new image dimensions, not allowing the width and height to be less than either the max width or height + * + * @param int $width + * @param int $height + */ + protected function calcImageSizeStrict($width, $height) + { + // first, we need to determine what the longest resize dimension is.. + if ($this->maxWidth >= $this->maxHeight) { + // and determine the longest original dimension + if ($width > $height) { + $newDimensions = $this->calcHeight($width, $height); + + if ($newDimensions['newWidth'] < $this->maxWidth) { + $newDimensions = $this->calcWidth($width, $height); + } + } elseif ($height >= $width) { + $newDimensions = $this->calcWidth($width, $height); + + if ($newDimensions['newHeight'] < $this->maxHeight) { + $newDimensions = $this->calcHeight($width, $height); + } + } + } elseif ($this->maxHeight > $this->maxWidth) { + if ($width >= $height) { + $newDimensions = $this->calcWidth($width, $height); + + if ($newDimensions['newHeight'] < $this->maxHeight) { + $newDimensions = $this->calcHeight($width, $height); + } + } elseif ($height > $width) { + $newDimensions = $this->calcHeight($width, $height); + + if ($newDimensions['newWidth'] < $this->maxWidth) { + $newDimensions = $this->calcWidth($width, $height); + } + } + } + + $this->newDimensions = $newDimensions; + } + + /** + * Calculates new dimensions based on $this->percent and the provided dimensions + * + * @param int $width + * @param int $height + */ + protected function calcImageSizePercent($width, $height) + { + if ($this->percent > 0) { + $this->newDimensions = $this->calcPercent($width, $height); + } + } + + /** + * Determines the file format by mime-type + * + * This function will throw exceptions for invalid images / mime-types + * + */ + protected function determineFormat() + { + $formatInfo = getimagesize($this->fileName); + + // non-image files will return false + if ($formatInfo === false) { + if ($this->remoteImage) { + throw new \Exception("Could not determine format of remote image: {$this->fileName}"); + } else { + throw new \Exception("File is not a valid image: {$this->fileName}"); + } + } + + $mimeType = isset($formatInfo['mime']) ? $formatInfo['mime'] : null; + + switch ($mimeType) { + case 'image/gif': + $this->format = 'GIF'; + break; + case 'image/jpeg': + $this->format = 'JPG'; + break; + case 'image/png': + $this->format = 'PNG'; + break; + default: + throw new \Exception("Image format not supported: {$mimeType}"); + } + } + + /** + * Makes sure the correct GD implementation exists for the file type + * + */ + protected function verifyFormatCompatiblity() + { + $isCompatible = true; + $gdInfo = gd_info(); + + switch ($this->format) { + case 'GIF': + $isCompatible = isset($gdInfo['GIF Create Support']); + break; + case 'JPG': + $isCompatible = (isset($gdInfo['JPG Support']) || isset($gdInfo['JPEG Support'])) ? true : false; + break; + case 'PNG': + $isCompatible = isset($gdInfo[$this->format . ' Support']); + break; + default: + $isCompatible = false; + } + + if (!$isCompatible) { + // one last check for "JPEG" instead + $isCompatible = isset($gdInfo['JPEG Support']); + + if (!$isCompatible) { + throw new \Exception("Your GD installation does not support {$this->format} image types"); + } + } + } + + /** + * Preserves the alpha or transparency for PNG and GIF files + * + * Alpha / transparency will not be preserved if the appropriate options are set to false. + * Also, the GIF transparency is pretty skunky (the results aren't awesome), but it works like a + * champ... that's the nature of GIFs tho, so no huge surprise. + * + * This functionality was originally suggested by commenter Aimi (no links / site provided) - Thanks! :) + * + */ + protected function preserveAlpha() + { + if ($this->format == 'PNG' && $this->options['preserveAlpha'] === true) { + imagealphablending($this->workingImage, false); + + $colorTransparent = imagecolorallocatealpha( + $this->workingImage, + $this->options['alphaMaskColor'][0], + $this->options['alphaMaskColor'][1], + $this->options['alphaMaskColor'][2], + 0 + ); + + imagefill($this->workingImage, 0, 0, $colorTransparent); + imagesavealpha($this->workingImage, true); + } + // preserve transparency in GIFs... this is usually pretty rough tho + if ($this->format == 'GIF' && $this->options['preserveTransparency'] === true) { + $colorTransparent = imagecolorallocate( + $this->workingImage, + $this->options['transparencyMaskColor'][0], + $this->options['transparencyMaskColor'][1], + $this->options['transparencyMaskColor'][2] + ); + + imagecolortransparent($this->workingImage, $colorTransparent); + imagetruecolortopalette($this->workingImage, true, 256); + } + } +} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/PHPThumb/PHPThumb.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/PHPThumb/PHPThumb.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/PHPThumb/PHPThumb.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/PHPThumb/PHPThumb.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/PHPThumb/PluginInterface.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/PHPThumb/PluginInterface.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/PHPThumb/PluginInterface.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/PHPThumb/PluginInterface.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/PHPThumb/Plugins/Reflection.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/PHPThumb/Plugins/Reflection.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/PHPThumb/Plugins/Reflection.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/PHPThumb/Plugins/Reflection.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Autoloader.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Autoloader.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Autoloader.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Autoloader.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Client.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Client.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Client.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Client.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/ClientContextInterface.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/ClientContextInterface.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/ClientContextInterface.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/ClientContextInterface.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/ClientException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/ClientException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/ClientException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/ClientException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/ClientInterface.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/ClientInterface.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/ClientInterface.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/ClientInterface.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Cluster/ClusterStrategy.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Cluster/ClusterStrategy.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Cluster/ClusterStrategy.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Cluster/ClusterStrategy.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Cluster/Distributor/DistributorInterface.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Cluster/Distributor/DistributorInterface.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Cluster/Distributor/DistributorInterface.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Cluster/Distributor/DistributorInterface.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Cluster/Distributor/EmptyRingException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Cluster/Distributor/EmptyRingException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Cluster/Distributor/EmptyRingException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Cluster/Distributor/EmptyRingException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Cluster/Distributor/HashRing.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Cluster/Distributor/HashRing.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Cluster/Distributor/HashRing.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Cluster/Distributor/HashRing.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Cluster/Distributor/KetamaRing.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Cluster/Distributor/KetamaRing.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Cluster/Distributor/KetamaRing.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Cluster/Distributor/KetamaRing.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Cluster/Hash/CRC16.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Cluster/Hash/CRC16.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Cluster/Hash/CRC16.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Cluster/Hash/CRC16.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Cluster/Hash/HashGeneratorInterface.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Cluster/Hash/HashGeneratorInterface.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Cluster/Hash/HashGeneratorInterface.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Cluster/Hash/HashGeneratorInterface.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Cluster/PredisStrategy.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Cluster/PredisStrategy.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Cluster/PredisStrategy.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Cluster/PredisStrategy.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Cluster/RedisStrategy.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Cluster/RedisStrategy.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Cluster/RedisStrategy.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Cluster/RedisStrategy.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Cluster/StrategyInterface.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Cluster/StrategyInterface.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Cluster/StrategyInterface.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Cluster/StrategyInterface.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Collection/Iterator/CursorBasedIterator.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Collection/Iterator/CursorBasedIterator.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Collection/Iterator/CursorBasedIterator.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Collection/Iterator/CursorBasedIterator.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Collection/Iterator/HashKey.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Collection/Iterator/HashKey.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Collection/Iterator/HashKey.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Collection/Iterator/HashKey.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Collection/Iterator/Keyspace.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Collection/Iterator/Keyspace.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Collection/Iterator/Keyspace.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Collection/Iterator/Keyspace.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Collection/Iterator/ListKey.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Collection/Iterator/ListKey.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Collection/Iterator/ListKey.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Collection/Iterator/ListKey.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Collection/Iterator/SetKey.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Collection/Iterator/SetKey.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Collection/Iterator/SetKey.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Collection/Iterator/SetKey.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Collection/Iterator/SortedSetKey.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Collection/Iterator/SortedSetKey.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Collection/Iterator/SortedSetKey.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Collection/Iterator/SortedSetKey.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/Command.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/Command.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/Command.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/Command.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/CommandInterface.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/CommandInterface.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/CommandInterface.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/CommandInterface.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ConnectionAuth.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ConnectionAuth.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ConnectionAuth.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ConnectionAuth.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ConnectionEcho.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ConnectionEcho.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ConnectionEcho.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ConnectionEcho.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ConnectionPing.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ConnectionPing.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ConnectionPing.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ConnectionPing.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ConnectionQuit.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ConnectionQuit.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ConnectionQuit.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ConnectionQuit.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ConnectionSelect.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ConnectionSelect.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ConnectionSelect.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ConnectionSelect.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/HashDelete.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/HashDelete.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/HashDelete.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/HashDelete.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/HashExists.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/HashExists.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/HashExists.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/HashExists.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/HashGet.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/HashGet.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/HashGet.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/HashGet.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/HashGetAll.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/HashGetAll.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/HashGetAll.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/HashGetAll.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/HashGetMultiple.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/HashGetMultiple.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/HashGetMultiple.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/HashGetMultiple.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/HashIncrementBy.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/HashIncrementBy.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/HashIncrementBy.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/HashIncrementBy.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/HashIncrementByFloat.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/HashIncrementByFloat.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/HashIncrementByFloat.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/HashIncrementByFloat.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/HashKeys.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/HashKeys.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/HashKeys.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/HashKeys.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/HashLength.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/HashLength.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/HashLength.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/HashLength.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/HashScan.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/HashScan.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/HashScan.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/HashScan.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/HashSet.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/HashSet.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/HashSet.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/HashSet.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/HashSetMultiple.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/HashSetMultiple.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/HashSetMultiple.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/HashSetMultiple.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/HashSetPreserve.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/HashSetPreserve.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/HashSetPreserve.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/HashSetPreserve.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/HashStringLength.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/HashStringLength.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/HashStringLength.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/HashStringLength.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/HashValues.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/HashValues.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/HashValues.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/HashValues.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/HyperLogLogAdd.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/HyperLogLogAdd.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/HyperLogLogAdd.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/HyperLogLogAdd.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/HyperLogLogCount.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/HyperLogLogCount.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/HyperLogLogCount.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/HyperLogLogCount.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/HyperLogLogMerge.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/HyperLogLogMerge.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/HyperLogLogMerge.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/HyperLogLogMerge.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyDelete.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyDelete.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyDelete.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyDelete.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyDump.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyDump.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyDump.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyDump.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyExists.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyExists.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyExists.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyExists.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyExpire.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyExpire.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyExpire.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyExpire.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyExpireAt.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyExpireAt.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyExpireAt.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyExpireAt.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyKeys.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyKeys.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyKeys.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyKeys.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyMigrate.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyMigrate.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyMigrate.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyMigrate.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyMove.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyMove.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyMove.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyMove.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyPersist.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyPersist.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyPersist.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyPersist.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyPreciseExpire.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyPreciseExpire.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyPreciseExpire.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyPreciseExpire.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyPreciseExpireAt.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyPreciseExpireAt.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyPreciseExpireAt.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyPreciseExpireAt.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyPreciseTimeToLive.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyPreciseTimeToLive.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyPreciseTimeToLive.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyPreciseTimeToLive.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyRandom.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyRandom.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyRandom.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyRandom.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyRename.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyRename.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyRename.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyRename.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyRenamePreserve.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyRenamePreserve.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyRenamePreserve.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyRenamePreserve.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyRestore.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyRestore.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyRestore.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyRestore.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyScan.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyScan.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyScan.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyScan.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeySort.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeySort.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeySort.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeySort.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyTimeToLive.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyTimeToLive.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyTimeToLive.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyTimeToLive.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyType.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyType.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/KeyType.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/KeyType.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ListIndex.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ListIndex.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ListIndex.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ListIndex.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ListInsert.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ListInsert.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ListInsert.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ListInsert.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ListLength.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ListLength.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ListLength.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ListLength.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ListPopFirst.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ListPopFirst.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ListPopFirst.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ListPopFirst.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ListPopFirstBlocking.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ListPopFirstBlocking.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ListPopFirstBlocking.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ListPopFirstBlocking.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ListPopLast.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ListPopLast.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ListPopLast.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ListPopLast.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ListPopLastBlocking.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ListPopLastBlocking.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ListPopLastBlocking.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ListPopLastBlocking.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ListPopLastPushHead.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ListPopLastPushHead.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ListPopLastPushHead.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ListPopLastPushHead.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ListPopLastPushHeadBlocking.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ListPopLastPushHeadBlocking.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ListPopLastPushHeadBlocking.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ListPopLastPushHeadBlocking.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ListPushHead.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ListPushHead.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ListPushHead.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ListPushHead.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ListPushHeadX.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ListPushHeadX.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ListPushHeadX.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ListPushHeadX.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ListPushTail.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ListPushTail.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ListPushTail.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ListPushTail.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ListPushTailX.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ListPushTailX.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ListPushTailX.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ListPushTailX.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ListRange.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ListRange.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ListRange.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ListRange.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ListRemove.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ListRemove.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ListRemove.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ListRemove.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ListSet.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ListSet.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ListSet.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ListSet.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ListTrim.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ListTrim.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ListTrim.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ListTrim.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/PrefixableCommandInterface.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/PrefixableCommandInterface.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/PrefixableCommandInterface.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/PrefixableCommandInterface.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/Processor/KeyPrefixProcessor.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/Processor/KeyPrefixProcessor.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/Processor/KeyPrefixProcessor.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/Processor/KeyPrefixProcessor.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/Processor/ProcessorChain.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/Processor/ProcessorChain.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/Processor/ProcessorChain.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/Processor/ProcessorChain.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/Processor/ProcessorInterface.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/Processor/ProcessorInterface.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/Processor/ProcessorInterface.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/Processor/ProcessorInterface.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/PubSubPublish.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/PubSubPublish.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/PubSubPublish.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/PubSubPublish.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/PubSubPubsub.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/PubSubPubsub.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/PubSubPubsub.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/PubSubPubsub.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/PubSubSubscribe.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/PubSubSubscribe.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/PubSubSubscribe.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/PubSubSubscribe.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/PubSubSubscribeByPattern.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/PubSubSubscribeByPattern.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/PubSubSubscribeByPattern.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/PubSubSubscribeByPattern.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/PubSubUnsubscribe.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/PubSubUnsubscribe.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/PubSubUnsubscribe.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/PubSubUnsubscribe.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/PubSubUnsubscribeByPattern.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/PubSubUnsubscribeByPattern.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/PubSubUnsubscribeByPattern.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/PubSubUnsubscribeByPattern.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/RawCommand.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/RawCommand.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/RawCommand.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/RawCommand.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ScriptCommand.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ScriptCommand.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ScriptCommand.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ScriptCommand.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerBackgroundRewriteAOF.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerBackgroundRewriteAOF.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerBackgroundRewriteAOF.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerBackgroundRewriteAOF.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerBackgroundSave.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerBackgroundSave.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerBackgroundSave.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerBackgroundSave.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerClient.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerClient.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerClient.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerClient.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerCommand.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerCommand.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerCommand.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerCommand.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerConfig.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerConfig.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerConfig.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerConfig.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerDatabaseSize.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerDatabaseSize.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerDatabaseSize.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerDatabaseSize.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerEval.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerEval.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerEval.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerEval.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerEvalSHA.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerEvalSHA.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerEvalSHA.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerEvalSHA.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerFlushAll.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerFlushAll.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerFlushAll.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerFlushAll.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerFlushDatabase.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerFlushDatabase.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerFlushDatabase.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerFlushDatabase.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerInfo.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerInfo.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerInfo.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerInfo.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerInfoV26x.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerInfoV26x.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerInfoV26x.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerInfoV26x.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerLastSave.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerLastSave.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerLastSave.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerLastSave.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerMonitor.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerMonitor.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerMonitor.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerMonitor.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerObject.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerObject.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerObject.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerObject.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerSave.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerSave.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerSave.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerSave.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerScript.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerScript.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerScript.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerScript.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerSentinel.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerSentinel.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerSentinel.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerSentinel.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerShutdown.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerShutdown.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerShutdown.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerShutdown.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerSlaveOf.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerSlaveOf.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerSlaveOf.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerSlaveOf.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerSlowlog.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerSlowlog.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerSlowlog.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerSlowlog.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerTime.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerTime.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ServerTime.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ServerTime.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/SetAdd.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/SetAdd.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/SetAdd.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/SetAdd.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/SetCardinality.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/SetCardinality.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/SetCardinality.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/SetCardinality.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/SetDifference.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/SetDifference.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/SetDifference.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/SetDifference.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/SetDifferenceStore.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/SetDifferenceStore.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/SetDifferenceStore.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/SetDifferenceStore.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/SetIntersection.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/SetIntersection.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/SetIntersection.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/SetIntersection.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/SetIntersectionStore.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/SetIntersectionStore.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/SetIntersectionStore.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/SetIntersectionStore.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/SetIsMember.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/SetIsMember.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/SetIsMember.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/SetIsMember.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/SetMembers.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/SetMembers.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/SetMembers.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/SetMembers.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/SetMove.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/SetMove.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/SetMove.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/SetMove.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/SetPop.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/SetPop.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/SetPop.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/SetPop.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/SetRandomMember.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/SetRandomMember.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/SetRandomMember.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/SetRandomMember.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/SetRemove.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/SetRemove.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/SetRemove.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/SetRemove.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/SetScan.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/SetScan.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/SetScan.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/SetScan.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/SetUnion.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/SetUnion.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/SetUnion.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/SetUnion.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/SetUnionStore.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/SetUnionStore.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/SetUnionStore.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/SetUnionStore.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringAppend.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringAppend.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringAppend.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringAppend.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringBitCount.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringBitCount.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringBitCount.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringBitCount.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringBitOp.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringBitOp.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringBitOp.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringBitOp.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringBitPos.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringBitPos.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringBitPos.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringBitPos.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringDecrement.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringDecrement.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringDecrement.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringDecrement.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringDecrementBy.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringDecrementBy.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringDecrementBy.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringDecrementBy.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringGet.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringGet.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringGet.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringGet.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringGetBit.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringGetBit.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringGetBit.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringGetBit.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringGetMultiple.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringGetMultiple.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringGetMultiple.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringGetMultiple.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringGetRange.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringGetRange.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringGetRange.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringGetRange.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringGetSet.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringGetSet.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringGetSet.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringGetSet.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringIncrement.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringIncrement.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringIncrement.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringIncrement.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringIncrementBy.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringIncrementBy.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringIncrementBy.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringIncrementBy.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringIncrementByFloat.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringIncrementByFloat.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringIncrementByFloat.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringIncrementByFloat.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringPreciseSetExpire.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringPreciseSetExpire.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringPreciseSetExpire.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringPreciseSetExpire.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringSet.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringSet.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringSet.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringSet.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringSetBit.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringSetBit.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringSetBit.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringSetBit.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringSetExpire.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringSetExpire.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringSetExpire.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringSetExpire.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringSetMultiple.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringSetMultiple.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringSetMultiple.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringSetMultiple.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringSetMultiplePreserve.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringSetMultiplePreserve.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringSetMultiplePreserve.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringSetMultiplePreserve.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringSetPreserve.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringSetPreserve.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringSetPreserve.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringSetPreserve.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringSetRange.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringSetRange.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringSetRange.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringSetRange.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringStrlen.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringStrlen.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringStrlen.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringStrlen.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringSubstr.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringSubstr.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/StringSubstr.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/StringSubstr.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/TransactionDiscard.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/TransactionDiscard.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/TransactionDiscard.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/TransactionDiscard.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/TransactionExec.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/TransactionExec.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/TransactionExec.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/TransactionExec.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/TransactionMulti.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/TransactionMulti.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/TransactionMulti.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/TransactionMulti.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/TransactionUnwatch.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/TransactionUnwatch.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/TransactionUnwatch.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/TransactionUnwatch.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/TransactionWatch.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/TransactionWatch.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/TransactionWatch.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/TransactionWatch.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetAdd.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetAdd.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetAdd.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetAdd.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetCardinality.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetCardinality.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetCardinality.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetCardinality.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetCount.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetCount.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetCount.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetCount.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetIncrementBy.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetIncrementBy.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetIncrementBy.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetIncrementBy.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetIntersectionStore.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetIntersectionStore.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetIntersectionStore.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetIntersectionStore.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetLexCount.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetLexCount.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetLexCount.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetLexCount.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetRange.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetRange.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetRange.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetRange.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetRangeByLex.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetRangeByLex.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetRangeByLex.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetRangeByLex.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetRangeByScore.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetRangeByScore.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetRangeByScore.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetRangeByScore.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetRank.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetRank.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetRank.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetRank.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetRemove.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetRemove.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetRemove.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetRemove.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetRemoveRangeByLex.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetRemoveRangeByLex.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetRemoveRangeByLex.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetRemoveRangeByLex.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetRemoveRangeByRank.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetRemoveRangeByRank.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetRemoveRangeByRank.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetRemoveRangeByRank.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetRemoveRangeByScore.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetRemoveRangeByScore.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetRemoveRangeByScore.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetRemoveRangeByScore.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetReverseRange.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetReverseRange.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetReverseRange.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetReverseRange.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetReverseRangeByLex.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetReverseRangeByLex.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetReverseRangeByLex.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetReverseRangeByLex.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetReverseRangeByScore.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetReverseRangeByScore.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetReverseRangeByScore.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetReverseRangeByScore.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetReverseRank.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetReverseRank.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetReverseRank.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetReverseRank.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetScan.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetScan.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetScan.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetScan.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetScore.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetScore.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetScore.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetScore.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetUnionStore.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetUnionStore.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Command/ZSetUnionStore.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Command/ZSetUnionStore.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/CommunicationException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/CommunicationException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/CommunicationException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/CommunicationException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Configuration/ClusterOption.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Configuration/ClusterOption.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Configuration/ClusterOption.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Configuration/ClusterOption.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Configuration/ConnectionFactoryOption.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Configuration/ConnectionFactoryOption.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Configuration/ConnectionFactoryOption.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Configuration/ConnectionFactoryOption.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Configuration/ExceptionsOption.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Configuration/ExceptionsOption.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Configuration/ExceptionsOption.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Configuration/ExceptionsOption.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Configuration/OptionInterface.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Configuration/OptionInterface.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Configuration/OptionInterface.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Configuration/OptionInterface.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Configuration/Options.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Configuration/Options.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Configuration/Options.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Configuration/Options.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Configuration/OptionsInterface.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Configuration/OptionsInterface.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Configuration/OptionsInterface.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Configuration/OptionsInterface.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Configuration/PrefixOption.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Configuration/PrefixOption.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Configuration/PrefixOption.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Configuration/PrefixOption.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Configuration/ProfileOption.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Configuration/ProfileOption.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Configuration/ProfileOption.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Configuration/ProfileOption.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Configuration/ReplicationOption.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Configuration/ReplicationOption.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Configuration/ReplicationOption.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Configuration/ReplicationOption.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/AbstractConnection.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/AbstractConnection.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/AbstractConnection.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/AbstractConnection.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/Aggregate/ClusterInterface.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/Aggregate/ClusterInterface.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/Aggregate/ClusterInterface.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/Aggregate/ClusterInterface.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/Aggregate/MasterSlaveReplication.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/Aggregate/MasterSlaveReplication.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/Aggregate/MasterSlaveReplication.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/Aggregate/MasterSlaveReplication.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/Aggregate/PredisCluster.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/Aggregate/PredisCluster.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/Aggregate/PredisCluster.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/Aggregate/PredisCluster.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/Aggregate/RedisCluster.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/Aggregate/RedisCluster.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/Aggregate/RedisCluster.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/Aggregate/RedisCluster.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/Aggregate/ReplicationInterface.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/Aggregate/ReplicationInterface.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/Aggregate/ReplicationInterface.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/Aggregate/ReplicationInterface.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/AggregateConnectionInterface.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/AggregateConnectionInterface.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/AggregateConnectionInterface.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/AggregateConnectionInterface.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/CompositeConnectionInterface.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/CompositeConnectionInterface.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/CompositeConnectionInterface.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/CompositeConnectionInterface.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/CompositeStreamConnection.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/CompositeStreamConnection.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/CompositeStreamConnection.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/CompositeStreamConnection.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/ConnectionException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/ConnectionException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/ConnectionException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/ConnectionException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/ConnectionInterface.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/ConnectionInterface.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/ConnectionInterface.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/ConnectionInterface.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/Factory.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/Factory.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/Factory.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/Factory.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/FactoryInterface.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/FactoryInterface.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/FactoryInterface.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/FactoryInterface.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/NodeConnectionInterface.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/NodeConnectionInterface.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/NodeConnectionInterface.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/NodeConnectionInterface.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/Parameters.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/Parameters.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/Parameters.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/Parameters.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/ParametersInterface.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/ParametersInterface.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/ParametersInterface.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/ParametersInterface.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/PhpiredisSocketConnection.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/PhpiredisSocketConnection.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/PhpiredisSocketConnection.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/PhpiredisSocketConnection.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/PhpiredisStreamConnection.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/PhpiredisStreamConnection.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/PhpiredisStreamConnection.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/PhpiredisStreamConnection.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/StreamConnection.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/StreamConnection.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/StreamConnection.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/StreamConnection.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/WebdisConnection.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/WebdisConnection.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Connection/WebdisConnection.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Connection/WebdisConnection.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Monitor/Consumer.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Monitor/Consumer.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Monitor/Consumer.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Monitor/Consumer.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/NotSupportedException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/NotSupportedException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/NotSupportedException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/NotSupportedException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Pipeline/Atomic.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Pipeline/Atomic.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Pipeline/Atomic.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Pipeline/Atomic.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Pipeline/ConnectionErrorProof.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Pipeline/ConnectionErrorProof.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Pipeline/ConnectionErrorProof.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Pipeline/ConnectionErrorProof.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Pipeline/FireAndForget.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Pipeline/FireAndForget.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Pipeline/FireAndForget.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Pipeline/FireAndForget.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Pipeline/Pipeline.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Pipeline/Pipeline.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Pipeline/Pipeline.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Pipeline/Pipeline.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/PredisException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/PredisException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/PredisException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/PredisException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Profile/Factory.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Profile/Factory.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Profile/Factory.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Profile/Factory.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Profile/ProfileInterface.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Profile/ProfileInterface.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Profile/ProfileInterface.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Profile/ProfileInterface.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Profile/RedisProfile.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Profile/RedisProfile.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Profile/RedisProfile.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Profile/RedisProfile.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Profile/RedisUnstable.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Profile/RedisUnstable.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Profile/RedisUnstable.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Profile/RedisUnstable.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Profile/RedisVersion200.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Profile/RedisVersion200.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Profile/RedisVersion200.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Profile/RedisVersion200.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Profile/RedisVersion220.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Profile/RedisVersion220.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Profile/RedisVersion220.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Profile/RedisVersion220.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Profile/RedisVersion240.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Profile/RedisVersion240.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Profile/RedisVersion240.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Profile/RedisVersion240.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Profile/RedisVersion260.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Profile/RedisVersion260.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Profile/RedisVersion260.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Profile/RedisVersion260.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Profile/RedisVersion280.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Profile/RedisVersion280.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Profile/RedisVersion280.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Profile/RedisVersion280.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Profile/RedisVersion300.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Profile/RedisVersion300.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Profile/RedisVersion300.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Profile/RedisVersion300.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Protocol/ProtocolException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Protocol/ProtocolException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Protocol/ProtocolException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Protocol/ProtocolException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Protocol/ProtocolProcessorInterface.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Protocol/ProtocolProcessorInterface.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Protocol/ProtocolProcessorInterface.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Protocol/ProtocolProcessorInterface.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Protocol/RequestSerializerInterface.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Protocol/RequestSerializerInterface.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Protocol/RequestSerializerInterface.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Protocol/RequestSerializerInterface.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Protocol/ResponseReaderInterface.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Protocol/ResponseReaderInterface.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Protocol/ResponseReaderInterface.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Protocol/ResponseReaderInterface.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Protocol/Text/CompositeProtocolProcessor.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Protocol/Text/CompositeProtocolProcessor.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Protocol/Text/CompositeProtocolProcessor.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Protocol/Text/CompositeProtocolProcessor.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Protocol/Text/Handler/BulkResponse.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Protocol/Text/Handler/BulkResponse.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Protocol/Text/Handler/BulkResponse.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Protocol/Text/Handler/BulkResponse.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Protocol/Text/Handler/ErrorResponse.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Protocol/Text/Handler/ErrorResponse.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Protocol/Text/Handler/ErrorResponse.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Protocol/Text/Handler/ErrorResponse.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Protocol/Text/Handler/IntegerResponse.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Protocol/Text/Handler/IntegerResponse.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Protocol/Text/Handler/IntegerResponse.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Protocol/Text/Handler/IntegerResponse.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Protocol/Text/Handler/MultiBulkResponse.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Protocol/Text/Handler/MultiBulkResponse.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Protocol/Text/Handler/MultiBulkResponse.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Protocol/Text/Handler/MultiBulkResponse.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Protocol/Text/Handler/ResponseHandlerInterface.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Protocol/Text/Handler/ResponseHandlerInterface.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Protocol/Text/Handler/ResponseHandlerInterface.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Protocol/Text/Handler/ResponseHandlerInterface.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Protocol/Text/Handler/StatusResponse.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Protocol/Text/Handler/StatusResponse.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Protocol/Text/Handler/StatusResponse.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Protocol/Text/Handler/StatusResponse.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Protocol/Text/Handler/StreamableMultiBulkResponse.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Protocol/Text/Handler/StreamableMultiBulkResponse.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Protocol/Text/Handler/StreamableMultiBulkResponse.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Protocol/Text/Handler/StreamableMultiBulkResponse.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Protocol/Text/ProtocolProcessor.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Protocol/Text/ProtocolProcessor.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Protocol/Text/ProtocolProcessor.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Protocol/Text/ProtocolProcessor.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Protocol/Text/RequestSerializer.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Protocol/Text/RequestSerializer.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Protocol/Text/RequestSerializer.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Protocol/Text/RequestSerializer.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Protocol/Text/ResponseReader.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Protocol/Text/ResponseReader.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Protocol/Text/ResponseReader.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Protocol/Text/ResponseReader.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/PubSub/AbstractConsumer.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/PubSub/AbstractConsumer.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/PubSub/AbstractConsumer.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/PubSub/AbstractConsumer.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/PubSub/Consumer.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/PubSub/Consumer.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/PubSub/Consumer.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/PubSub/Consumer.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/PubSub/DispatcherLoop.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/PubSub/DispatcherLoop.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/PubSub/DispatcherLoop.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/PubSub/DispatcherLoop.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Replication/ReplicationStrategy.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Replication/ReplicationStrategy.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Replication/ReplicationStrategy.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Replication/ReplicationStrategy.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Response/Error.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Response/Error.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Response/Error.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Response/Error.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Response/ErrorInterface.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Response/ErrorInterface.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Response/ErrorInterface.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Response/ErrorInterface.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Response/Iterator/MultiBulk.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Response/Iterator/MultiBulk.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Response/Iterator/MultiBulk.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Response/Iterator/MultiBulk.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Response/Iterator/MultiBulkIterator.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Response/Iterator/MultiBulkIterator.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Response/Iterator/MultiBulkIterator.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Response/Iterator/MultiBulkIterator.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Response/Iterator/MultiBulkTuple.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Response/Iterator/MultiBulkTuple.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Response/Iterator/MultiBulkTuple.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Response/Iterator/MultiBulkTuple.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Response/ResponseInterface.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Response/ResponseInterface.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Response/ResponseInterface.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Response/ResponseInterface.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Response/ServerException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Response/ServerException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Response/ServerException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Response/ServerException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Response/Status.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Response/Status.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Response/Status.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Response/Status.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Session/Handler.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Session/Handler.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Session/Handler.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Session/Handler.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Transaction/AbortedMultiExecException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Transaction/AbortedMultiExecException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Transaction/AbortedMultiExecException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Transaction/AbortedMultiExecException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Transaction/MultiExec.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Transaction/MultiExec.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Transaction/MultiExec.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Transaction/MultiExec.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Transaction/MultiExecState.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Transaction/MultiExecState.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/Predis/Transaction/MultiExecState.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/Predis/Transaction/MultiExecState.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/RainLoop/Actions.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/RainLoop/Actions.php similarity index 96% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/RainLoop/Actions.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/RainLoop/Actions.php index 2ae8e10de884f648d3ddf563bfd180812284b14b..001026720680fc3774299f7c876f2a3d1312efd6 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/RainLoop/Actions.php +++ b/rainloop/app/rainloop/v/1.12.1/app/libraries/RainLoop/Actions.php @@ -1,10269 +1,10269 @@ -aCurrentActionParams = array(); - - $this->oHttp = null; - $this->oLogger = null; - $this->oPlugins = null; - $this->oMailClient = null; - $this->oSocial = null; - $this->oConfig = null; - $this->aCachers = array(); - - $this->oStorageProvider = null; - $this->oLocalStorageProvider = null; - $this->oSettingsProvider = null; - $this->oLocalSettingsProvider = null; - $this->oFilesProvider = null; - $this->oFiltersProvider = null; - $this->oDomainProvider = null; - $this->oAddressBookProvider = null; - $this->oSuggestionsProvider = null; - $this->oChangePasswordProvider = null; - $this->oTwoFactorAuthProvider = null; - $this->oPremProvider = null; - - $this->sSpecAuthToken = ''; - - $oConfig = $this->Config(); - $this->Plugins()->RunHook('filter.application-config', array(&$oConfig)); - - $this->Logger()->Ping(); - } - - /** - * @return \RainLoop\Actions - */ - public static function NewInstance() - { - return new self(); - } - - /** - * @param string $sSpecAuthToken - * - * @return \RainLoop\Application - */ - public function SetSpecAuthToken($sSpecAuthToken) - { - $this->sSpecAuthToken = $sSpecAuthToken; - - return $this; - } - - /** - * @return string - */ - public function GetSpecAuthToken() - { - return $this->sSpecAuthToken; - } - - /** - * @return string - */ - public function GetShortLifeSpecAuthToken($iLife = 60) - { - $aAccountHash = \RainLoop\Utils::DecodeKeyValues($this->getLocalAuthToken()); - if (!empty($aAccountHash[0]) && 'token' === $aAccountHash[0] && \is_array($aAccountHash)) - { - $aAccountHash[10] = \time() + $iLife; - return \RainLoop\Utils::EncodeKeyValues($aAccountHash); - } - - return ''; - } - - /** - * @return \RainLoop\Application - */ - public function Config() - { - if (null === $this->oConfig) - { - $this->oConfig = new \RainLoop\Config\Application(); - if (!$this->oConfig->Load()) - { - usleep(10000); - $this->oConfig->Load(); - } - -// if (!$bLoaded && !$this->oConfig->IsFileExists()) -// { -// $bSave = true; -// } -// -// if ($bLoaded && !$bSave) -// { -// $bSave = APP_VERSION !== $this->oConfig->Get('version', 'current'); -// } -// -// if ($bSave) -// { -// $this->oConfig->Save(); -// } - } - - return $this->oConfig; - } - - /** - * @param string $sName - * @param \RainLoop\Model\Account $oAccount = null - * - * @return mixed - */ - private function fabrica($sName, $oAccount = null) - { - $mResult = null; - $this->Plugins() - ->RunHook('main.fabrica', array($sName, &$mResult), false) - ->RunHook('main.fabrica[2]', array($sName, &$mResult, $oAccount), false) - ; - - if (null === $mResult) - { - switch ($sName) - { - case 'files': - // RainLoop\Providers\Files\IFiles - $mResult = new \RainLoop\Providers\Files\FileStorage(APP_PRIVATE_DATA.'storage/files'); - break; - case 'storage': - case 'storage-local': - // RainLoop\Providers\Storage\IStorage - $mResult = new \RainLoop\Providers\Storage\FileStorage( - APP_PRIVATE_DATA.'storage', 'storage-local' === $sName); - break; - case 'settings': - case 'settings-local': - // RainLoop\Providers\Settings\ISettings - $mResult = new \RainLoop\Providers\Settings\DefaultSettings( - $this->StorageProvider('settings-local' === $sName)); - break; - case 'login': - // \RainLoop\Providers\Login\LoginInterface - $mResult = new \RainLoop\Providers\Login\DefaultLogin(); - break; - case 'domain': - // \RainLoop\Providers\Domain\DomainAdminInterface - $mResult = new \RainLoop\Providers\Domain\DefaultDomain(APP_PRIVATE_DATA.'domains', $this->Cacher()); - break; - case 'filters': - // \RainLoop\Providers\Filters\FiltersInterface - $mResult = new \RainLoop\Providers\Filters\SieveStorage( - $this->Plugins(), $this->Config() - ); - break; - case 'address-book': - // \RainLoop\Providers\AddressBook\AddressBookInterface - - $sDsn = \trim($this->Config()->Get('contacts', 'pdo_dsn', '')); - $sUser = \trim($this->Config()->Get('contacts', 'pdo_user', '')); - $sPassword = (string) $this->Config()->Get('contacts', 'pdo_password', ''); - - $sDsnType = $this->ValidateContactPdoType(\trim($this->Config()->Get('contacts', 'type', 'sqlite'))); - if ('sqlite' === $sDsnType) - { - $mResult = new \RainLoop\Providers\AddressBook\PdoAddressBook( - 'sqlite:'.APP_PRIVATE_DATA.'AddressBook.sqlite', '', '', 'sqlite'); - } - else - { - $mResult = new \RainLoop\Providers\AddressBook\PdoAddressBook($sDsn, $sUser, $sPassword, $sDsnType); - } - break; - case 'suggestions': - - if (null === $mResult) - { - $mResult = array(); - } - - if (\is_array($mResult) && \RainLoop\Utils::IsOwnCloud() && $this->Config()->Get('labs', 'owncloud_suggestions', true)) - { - // \RainLoop\Providers\Suggestions\ISuggestions - $mResult[] = new \RainLoop\Providers\Suggestions\OwnCloudSuggestions(); - } - - break; - case 'change-password': - // \RainLoop\Providers\ChangePassword\ChangePasswordInterface - break; - case 'two-factor-auth': - // \RainLoop\Providers\TwoFactorAuth\TwoFactorAuthInterface - $mResult = new \RainLoop\Providers\TwoFactorAuth\GoogleTwoFactorAuth(); - break; - } - } - - foreach (\is_array($mResult) ? $mResult : array($mResult) as $oItem) - { - if ($oItem && \method_exists($oItem, 'SetLogger')) - { - $oItem->SetLogger($this->Logger()); - } - } - - $this->Plugins()->RunHook('filter.fabrica', array($sName, &$mResult, $oAccount), false); - - return $mResult; - } - - /** - * @return void - */ - public function BootStart() - { - if (defined('APP_INSTALLED_START') && defined('APP_INSTALLED_VERSION') && - APP_INSTALLED_START && !APP_INSTALLED_VERSION) - { - try - { - $this->KeenIO('Install'); - } - catch (\Exception $oException) { unset($oException); } - } - } - - /** - * @return void - */ - public function BootEnd() - { - try - { - if ($this->MailClient()->IsLoggined()) - { - $this->MailClient()->LogoutAndDisconnect(); - } - } - catch (\Exception $oException) { unset($oException); } - } - - /** - * @return string - */ - public function ParseQueryAuthString() - { - $sQuery = \trim($this->Http()->GetQueryString()); - - $iPos = \strpos($sQuery, '&'); - if (0 < $iPos) - { - $sQuery = \substr($sQuery, 0, $iPos); - } - - $sQuery = \trim(\trim($sQuery), ' /'); - - $aSubQuery = $this->Http()->GetQuery('q', null); - if (\is_array($aSubQuery)) - { - $aSubQuery = \array_map(function ($sS) { - return \trim(\trim($sS), ' /'); - }, $aSubQuery); - - if (0 < \count($aSubQuery)) - { - $sQuery .= '/'.\implode('/', $aSubQuery); - } - } - - if ('' === $this->GetSpecAuthToken()) - { - $aPaths = \explode('/', $sQuery); - if (!empty($aPaths[0]) && !empty($aPaths[1]) && '_' === substr($aPaths[1], 0, 1)) - { - $this->SetSpecAuthToken($aPaths[1]); - } - } - - return $sQuery; - } - - /** - * @param string $sLine - * @param \RainLoop\Model\Account $oAccount = null - * @param bool $bUrlEncode = false - * @param array $aAdditionalParams = array() - * - * @return string - */ - private function compileLogParams($sLine, $oAccount = null, $bUrlEncode = false, $aAdditionalParams = array()) - { - $aClear = array(); - - if (false !== \strpos($sLine, '{date:')) - { - $sTimeOffset = (string) $this->Config()->Get('logs', 'time_offset', '0'); - $sLine = \preg_replace_callback('/\{date:([^}]+)\}/', function ($aMatch) use ($sTimeOffset, $bUrlEncode) { - return \RainLoop\Utils::UrlEncode(\MailSo\Log\Logger::DateHelper($aMatch[1], $sTimeOffset), $bUrlEncode); - }, $sLine); - - $aClear['/\{date:([^}]*)\}/'] = 'date'; - } - - if (false !== \strpos($sLine, '{imap:') || false !== \strpos($sLine, '{smtp:')) - { - if (!$oAccount) - { - $this->ParseQueryAuthString(); - $oAccount = $this->getAccountFromToken(false); - } - - if ($oAccount) - { - $sLine = \str_replace('{imap:login}', \RainLoop\Utils::UrlEncode($oAccount->IncLogin(), $bUrlEncode), $sLine); - $sLine = \str_replace('{imap:host}', \RainLoop\Utils::UrlEncode($oAccount->DomainIncHost(), $bUrlEncode), $sLine); - $sLine = \str_replace('{imap:port}', \RainLoop\Utils::UrlEncode($oAccount->DomainIncPort(), $bUrlEncode), $sLine); - - $sLine = \str_replace('{smtp:login}', \RainLoop\Utils::UrlEncode($oAccount->OutLogin(), $bUrlEncode), $sLine); - $sLine = \str_replace('{smtp:host}', \RainLoop\Utils::UrlEncode($oAccount->DomainOutHost(), $bUrlEncode), $sLine); - $sLine = \str_replace('{smtp:port}', \RainLoop\Utils::UrlEncode($oAccount->DomainOutPort(), $bUrlEncode), $sLine); - } - - $aClear['/\{imap:([^}]*)\}/i'] = 'imap'; - $aClear['/\{smtp:([^}]*)\}/i'] = 'smtp'; - } - - if (false !== \strpos($sLine, '{request:')) - { - if (false !== \strpos($sLine, '{request:ip}')) - { - $sLine = \str_replace('{request:ip}', \RainLoop\Utils::UrlEncode($this->Http()->GetClientIp( - $this->Config()->Get('labs', 'http_client_ip_check_proxy', false)), $bUrlEncode), $sLine); - } - - if (false !== \strpos($sLine, '{request:domain}')) - { - $sLine = \str_replace('{request:domain}', - \RainLoop\Utils::UrlEncode($this->Http()->GetHost(false, true, true), $bUrlEncode), $sLine); - } - - if (false !== \strpos($sLine, '{request:domain-clear}')) - { - $sLine = \str_replace('{request:domain-clear}', - \RainLoop\Utils::UrlEncode( - \MailSo\Base\Utils::GetClearDomainName($this->Http()->GetHost(false, true, true)), $bUrlEncode), $sLine); - } - - $aClear['/\{request:([^}]*)\}/i'] = 'request'; - } - - if (false !== \strpos($sLine, '{user:')) - { - if (false !== \strpos($sLine, '{user:uid}')) - { - $sLine = \str_replace('{user:uid}', - \RainLoop\Utils::UrlEncode(\base_convert(\sprintf('%u', - \crc32(\md5(\RainLoop\Utils::GetConnectionToken()))), 10, 32), $bUrlEncode), - $sLine - ); - } - - if (false !== \strpos($sLine, '{user:ip}')) - { - $sLine = \str_replace('{user:ip}', \RainLoop\Utils::UrlEncode($this->Http()->GetClientIp( - $this->Config()->Get('labs', 'http_client_ip_check_proxy', false)), $bUrlEncode), $sLine); - } - - if (\preg_match('/\{user:(email|login|domain)\}/i', $sLine)) - { - if (!$oAccount) - { - $this->ParseQueryAuthString(); - $oAccount = $this->getAccountFromToken(false); - } - - if ($oAccount) - { - $sEmail = $oAccount->Email(); - - $sLine = \str_replace('{user:email}', \RainLoop\Utils::UrlEncode($sEmail, $bUrlEncode), $sLine); - $sLine = \str_replace('{user:login}', \RainLoop\Utils::UrlEncode( - \MailSo\Base\Utils::GetAccountNameFromEmail($sEmail), $bUrlEncode), $sLine); - $sLine = \str_replace('{user:domain}', \RainLoop\Utils::UrlEncode( - \MailSo\Base\Utils::GetDomainFromEmail($sEmail), $bUrlEncode), $sLine); - $sLine = \str_replace('{user:domain-clear}', \RainLoop\Utils::UrlEncode( - \MailSo\Base\Utils::GetClearDomainName( - \MailSo\Base\Utils::GetDomainFromEmail($sEmail)), $bUrlEncode), $sLine); - } - } - - $aClear['/\{user:([^}]*)\}/i'] = 'unknown'; - } - - if (false !== \strpos($sLine, '{labs:')) - { - $sLine = \preg_replace_callback('/\{labs:rand:([1-9])\}/', function ($aMatch) { - return \rand(\pow(10, $aMatch[1] - 1), \pow(10, $aMatch[1]) - 1); - }, $sLine); - - $aClear['/\{labs:([^}]*)\}/'] = 'labs'; - } - - if (\is_array($aAdditionalParams) && 0 < \count($aAdditionalParams)) - { - foreach ($aAdditionalParams as $sKey => $sValue) - { - $sLine = \str_replace($sKey, $sValue, $sLine); - } - } - - if (0 < \count($aClear)) - { - foreach ($aClear as $sKey => $sValue) - { - $sLine = \preg_replace($sKey, $sValue, $sLine); - } - } - - return $sLine; - } - - /** - * @param string $sFileName - * - * @return string - */ - private function compileLogFileName($sFileName) - { - $sFileName = \trim($sFileName); - - if (0 !== \strlen($sFileName)) - { - $sFileName = $this->compileLogParams($sFileName); - - $sFileName = \preg_replace('/[\/]+/', '/', \preg_replace('/[.]+/', '.', $sFileName)); - $sFileName = \preg_replace('/[^a-zA-Z0-9@_+=\-\.\/!()\[\]]/', '', $sFileName); - } - - if (0 === \strlen($sFileName)) - { - $sFileName = 'rainloop-log.txt'; - } - - return $sFileName; - } - - /** - * @return void - */ - public function SetAuthLogoutToken() - { - @\header('X-RainLoop-Action: Logout'); - \RainLoop\Utils::SetCookie(self::AUTH_SPEC_LOGOUT_TOKEN_KEY, \md5(APP_START_TIME), 0); - } - - /** - * @param \RainLoop\Model\Account $oAccount - * - * @return void - */ - public function SetAuthToken($oAccount) - { - if ($oAccount) - { - $sSpecAuthToken = '_'.$oAccount->GetAuthTokenQ(); - - $this->SetSpecAuthToken($sSpecAuthToken); - \RainLoop\Utils::SetCookie(self::AUTH_SPEC_TOKEN_KEY, $sSpecAuthToken, 0); - - if ($oAccount->SignMe() && 0 < \strlen($oAccount->SignMeToken())) - { - \RainLoop\Utils::SetCookie(self::AUTH_SIGN_ME_TOKEN_KEY, - \RainLoop\Utils::EncodeKeyValuesQ(array( - 'e' => $oAccount->Email(), - 't' => $oAccount->SignMeToken() - )), - \time() + 60 * 60 * 24 * 30); - - $this->StorageProvider()->Put($oAccount, - \RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG, - 'sign_me', - \RainLoop\Utils::EncodeKeyValuesQ(array( - 'Time' => \time(), - 'AuthToken' => $oAccount->GetAuthTokenQ(), - 'SignMetToken' => $oAccount->SignMeToken() - )) - ); - } - } - } - - /** - * @return string - */ - public function GetSpecAuthTokenWithDeletion() - { - $sResult = \RainLoop\Utils::GetCookie(self::AUTH_SPEC_TOKEN_KEY, ''); - if (0 < strlen($sResult)) - { - \RainLoop\Utils::ClearCookie(self::AUTH_SPEC_TOKEN_KEY); - } - - return $sResult; - } - - /** - * @return string - */ - public function GetSpecAuthLogoutTokenWithDeletion() - { - $sResult = \RainLoop\Utils::GetCookie(self::AUTH_SPEC_LOGOUT_TOKEN_KEY, ''); - if (0 < strlen($sResult)) - { - \RainLoop\Utils::ClearCookie(self::AUTH_SPEC_LOGOUT_TOKEN_KEY); - } - - return $sResult; - } - - /** - * @return string - */ - public function GetSpecLogoutCustomMgsWithDeletion() - { - $sResult = \RainLoop\Utils::GetCookie(self::AUTH_SPEC_LOGOUT_CUSTOM_MSG_KEY, ''); - if (0 < strlen($sResult)) - { - \RainLoop\Utils::ClearCookie(self::AUTH_SPEC_LOGOUT_CUSTOM_MSG_KEY); - } - - return $sResult; - } - - /** - * @return string - */ - public function SetSpecLogoutCustomMgsWithDeletion($sMessage) - { - \RainLoop\Utils::SetCookie(self::AUTH_SPEC_LOGOUT_CUSTOM_MSG_KEY, $sMessage, 0); - } - - /** - * @return void - */ - private function setAdminAuthToken($sToken) - { - \RainLoop\Utils::SetCookie(self::AUTH_ADMIN_TOKEN_KEY, $sToken, 0); - } - - /** - * @return string - */ - private function getLocalAuthToken() - { - $sToken = $this->GetSpecAuthToken(); - return !empty($sToken) && '_' === \substr($sToken, 0, 1) ? \substr($sToken, 1) : ''; - } - - /** - * @return string - */ - private function getAdminAuthToken() - { - return \RainLoop\Utils::GetCookie(self::AUTH_ADMIN_TOKEN_KEY, ''); - } - - /** - * @return void - */ - public function ClearAdminAuthToken() - { - $aAdminHash = \RainLoop\Utils::DecodeKeyValuesQ($this->getAdminAuthToken()); - if ( - !empty($aAdminHash[0]) && !empty($aAdminHash[1]) && !empty($aAdminHash[2]) && - 'token' === $aAdminHash[0] && \md5(APP_SALT) === $aAdminHash[1] - ) - { - $this->Cacher(null, true)->Delete(\RainLoop\KeyPathHelper::SessionAdminKey($aAdminHash[2])); - } - - \RainLoop\Utils::ClearCookie(self::AUTH_ADMIN_TOKEN_KEY); - } - - /** - * @param bool $bThrowExceptionOnFalse = false - * - * @return \RainLoop\Model\Account|bool - * @throws \RainLoop\Exceptions\ClientException - */ - public function GetAccount($bThrowExceptionOnFalse = false) - { - return $this->getAccountFromToken($bThrowExceptionOnFalse); - } - - /** - * @return \MailSo\Base\Http - */ - public function Http() - { - if (null === $this->oHttp) - { - $this->oHttp = \MailSo\Base\Http::SingletonInstance(); - } - - return $this->oHttp; - } - - /** - * @return \RainLoop\Social - */ - public function Social() - { - if (null === $this->oSocial) - { - $this->oSocial = new \RainLoop\Social($this->Http(), $this); - } - - return $this->oSocial; - } - - /** - * @return \MailSo\Mail\MailClient - */ - public function MailClient() - { - if (null === $this->oMailClient) - { - $this->oMailClient = \MailSo\Mail\MailClient::NewInstance(); - $this->oMailClient->SetLogger($this->Logger()); - } - - return $this->oMailClient; - } - - /** - * @return \RainLoop\Providers\Filters - */ - public function FiltersProvider() - { - if (null === $this->oFiltersProvider) - { - $this->oFiltersProvider = new \RainLoop\Providers\Filters( - $this->fabrica('filters')); - } - - return $this->oFiltersProvider; - } - - /** - * @return \RainLoop\Providers\ChangePassword - */ - public function ChangePasswordProvider() - { - if (null === $this->oChangePasswordProvider) - { - $this->oChangePasswordProvider = new \RainLoop\Providers\ChangePassword( - $this, $this->fabrica('change-password'), !!$this->Config()->Get('labs', 'check_new_password_strength', true) - ); - } - - return $this->oChangePasswordProvider; - } - - /** - * @return \RainLoop\Providers\TwoFactorAuth - */ - public function TwoFactorAuthProvider() - { - if (null === $this->oTwoFactorAuthProvider) - { - $this->oTwoFactorAuthProvider = new \RainLoop\Providers\TwoFactorAuth( - $this->Config()->Get('security', 'allow_two_factor_auth', false) ? $this->fabrica('two-factor-auth') : null - ); - } - - return $this->oTwoFactorAuthProvider; - } - - /** - * @return \RainLoop\Providers\Prem - */ - public function PremProvider() - { - if (null === $this->oPremProvider) - { - if (\file_exists(APP_VERSION_ROOT_PATH.'app/libraries/RainLoop/Providers/Prem.php')) - { - $this->oPremProvider = new \RainLoop\Providers\Prem( - $this->Config(), $this->Logger(), $this->Cacher(null, true) - ); - } - else - { - $this->oPremProvider = false; - } - } - - return $this->oPremProvider; - } - - /** - * @param bool $bLocal = false - * - * @return \RainLoop\Providers\Storage - */ - public function StorageProvider($bLocal = false) - { - if ($bLocal) - { - if (null === $this->oLocalStorageProvider) - { - $this->oLocalStorageProvider = new \RainLoop\Providers\Storage( - $this->fabrica('storage-local')); - } - - return $this->oLocalStorageProvider; - } - else - { - if (null === $this->oStorageProvider) - { - $this->oStorageProvider = new \RainLoop\Providers\Storage( - $this->fabrica('storage')); - } - - return $this->oStorageProvider; - } - - return null; - } - - /** - * @return \RainLoop\Providers\Settings - */ - public function SettingsProvider($bLocal = false) - { - if ($bLocal) - { - if (null === $this->oLocalSettingsProvider) - { - $this->oLocalSettingsProvider = new \RainLoop\Providers\Settings( - $this->fabrica('settings-local')); - } - - return $this->oLocalSettingsProvider; - } - else - { - if (null === $this->oSettingsProvider) - { - $this->oSettingsProvider = new \RainLoop\Providers\Settings( - $this->fabrica('settings')); - } - - return $this->oSettingsProvider; - } - - return null; - } - - /** - * @return \RainLoop\Providers\Files - */ - public function FilesProvider() - { - if (null === $this->oFilesProvider) - { - $this->oFilesProvider = new \RainLoop\Providers\Files( - $this->fabrica('files')); - } - - return $this->oFilesProvider; - } - - /** - * @return \RainLoop\Providers\Domain - */ - public function DomainProvider() - { - if (null === $this->oDomainProvider) - { - $this->oDomainProvider = new \RainLoop\Providers\Domain( - $this->fabrica('domain'), $this->Plugins()); - } - - return $this->oDomainProvider; - } - - /** - * @return \RainLoop\Providers\Suggestions - */ - public function SuggestionsProvider() - { - if (null === $this->oSuggestionsProvider) - { - $this->oSuggestionsProvider = new \RainLoop\Providers\Suggestions( - $this->fabrica('suggestions')); - } - - return $this->oSuggestionsProvider; - } - - /** - * @param \RainLoop\Model\Account $oAccount = null - * @param bool $bForceEnable = false - * - * @return \RainLoop\Providers\AddressBook - */ - public function AddressBookProvider($oAccount = null, $bForceEnable = false) - { - if (null === $this->oAddressBookProvider) - { - $oDriver = null; - if ($this->GetCapa(false, false, \RainLoop\Enumerations\Capa::CONTACTS, $oAccount)) - { - if ($this->Config()->Get('contacts', 'enable', false) || $bForceEnable) - { - $oDriver = $this->fabrica('address-book', $oAccount); - } - } - - $this->oAddressBookProvider = new \RainLoop\Providers\AddressBook($oDriver); - $this->oAddressBookProvider->SetLogger($this->Logger()); - } - - return $this->oAddressBookProvider; - } - - /** - * @param \RainLoop\Model\Account $oAccount = null - * @param bool $bForceFile = false - * - * @return \MailSo\Cache\CacheClient - */ - public function Cacher($oAccount = null, $bForceFile = false) - { - $sKey = ''; - if ($oAccount) - { - $sKey = $oAccount->ParentEmailHelper(); - } - - $sIndexKey = empty($sKey) ? '_default_' : $sKey; - if ($bForceFile) - { - $sIndexKey .= '/_files_'; - } - - if (!isset($this->aCachers[$sIndexKey])) - { - $this->aCachers[$sIndexKey] = \MailSo\Cache\CacheClient::NewInstance(); - - $oDriver = null; - $sDriver = \strtoupper(\trim($this->Config()->Get('cache', 'fast_cache_driver', 'files'))); - - switch (true) - { - default: - case $bForceFile: - $oDriver = \MailSo\Cache\Drivers\File::NewInstance(APP_PRIVATE_DATA.'cache', $sKey); - break; - - case ('APC' === $sDriver || 'APCU' === $sDriver) && - \MailSo\Base\Utils::FunctionExistsAndEnabled(array( - 'apc_store', 'apc_fetch', 'apc_delete', 'apc_clear_cache')): - - $oDriver = \MailSo\Cache\Drivers\APC::NewInstance($sKey); - break; - - case ('MEMCACHE' === $sDriver || 'MEMCACHED' === $sDriver) && - \MailSo\Base\Utils::FunctionExistsAndEnabled('memcache_connect'): - - $oDriver = \MailSo\Cache\Drivers\Memcache::NewInstance( - $this->Config()->Get('labs', 'fast_cache_memcache_host', '127.0.0.1'), - (int) $this->Config()->Get('labs', 'fast_cache_memcache_port', 11211), - 43200, - $sKey - ); - break; - - case 'REDIS' === $sDriver && \class_exists('Predis\Client'): - $oDriver = \MailSo\Cache\Drivers\Redis::NewInstance( - $this->Config()->Get('labs', 'fast_cache_redis_host', '127.0.0.1'), - (int) $this->Config()->Get('labs', 'fast_cache_redis_port', 6379), - 43200, - $sKey - ); - break; - } - - if ($oDriver) - { - $this->aCachers[$sIndexKey]->SetDriver($oDriver); - } - - $this->aCachers[$sIndexKey]->SetCacheIndex($this->Config()->Get('cache', 'fast_cache_index', '')); - } - - return $this->aCachers[$sIndexKey]; - } - - /** - * @return \RainLoop\Plugins\Manager - */ - public function Plugins() - { - if (null === $this->oPlugins) - { - $this->oPlugins = new \RainLoop\Plugins\Manager($this); - $this->oPlugins->SetLogger($this->Logger()); - } - - return $this->oPlugins; - } - - /** - * @return \MailSo\Log\Logger - */ - public function Logger() - { - if (null === $this->oLogger) - { - $this->oLogger = \MailSo\Log\Logger::SingletonInstance(); - - if (!!$this->Config()->Get('logs', 'enable', false)) - { - $sSessionFilter = (string) $this->Config()->Get('logs', 'session_filter', ''); - if (!empty($sSessionFilter)) - { - $aSessionParts = \explode(':', $sSessionFilter, 2); - - if (empty($aSessionParts[0]) || empty($aSessionParts[1]) || - (string) $aSessionParts[1] !== (string) \RainLoop\Utils::GetCookie($aSessionParts[0], '')) - { - return $this->oLogger; - } - } - - $sTimeOffset = (string) $this->Config()->Get('logs', 'time_offset', '0'); - - $this->oLogger->SetShowSecter(!$this->Config()->Get('logs', 'hide_passwords', true)); - - $sLogFileName = $this->Config()->Get('logs', 'filename', ''); - - $oDriver = null; - if ('syslog' === $sLogFileName) - { - $oDriver = \MailSo\Log\Drivers\Syslog::NewInstance(); - } - else - { - $sLogFileFullPath = \APP_PRIVATE_DATA.'logs/'.$this->compileLogFileName($sLogFileName); - $sLogFileDir = \dirname($sLogFileFullPath); - - if (!@is_dir($sLogFileDir)) - { - @mkdir($sLogFileDir, 0755, true); - } - - $oDriver = \MailSo\Log\Drivers\File::NewInstance($sLogFileFullPath); - } - - $this->oLogger->Add($oDriver - ->WriteOnErrorOnly($this->Config()->Get('logs', 'write_on_error_only', false)) - ->WriteOnPhpErrorOnly($this->Config()->Get('logs', 'write_on_php_error_only', false)) - ->WriteOnTimeoutOnly($this->Config()->Get('logs', 'write_on_timeout_only', 0)) - ->SetTimeOffset($sTimeOffset) - ); - - if (!$this->Config()->Get('debug', 'enable', false)) - { - $this->oLogger->AddForbiddenType(\MailSo\Log\Enumerations\Type::TIME); - } - - $this->oLogger->WriteEmptyLine(); - - $oHttp = $this->Http(); - - $this->oLogger->Write('[DATE:'.\MailSo\Log\Logger::DateHelper('d.m.y', $sTimeOffset). - (0 !== $sTimeOffset ? '][OFFSET:'.(0 < $sTimeOffset ? '+' : '-'). - \str_pad((string) \abs($sTimeOffset), 2, '0', STR_PAD_LEFT) : ''). - '][RL:'.APP_VERSION.'][PHP:'.PHP_VERSION.'][IP:'. - $oHttp->GetClientIp($this->Config()->Get('labs', 'http_client_ip_check_proxy', false)).'][PID:'. - (\MailSo\Base\Utils::FunctionExistsAndEnabled('getmypid') ? \getmypid() : 'unknown').']['. - $oHttp->GetServer('SERVER_SOFTWARE', '~').']['. - (\MailSo\Base\Utils::FunctionExistsAndEnabled('php_sapi_name') ? \php_sapi_name() : '~' ).']' - ); - - $sPdo = (\class_exists('PDO') ? \implode(',', \PDO::getAvailableDrivers()) : 'off'); - $sPdo = empty($sPdo) ? '~' : $sPdo; - - $this->oLogger->Write('['. - 'Suhosin:'.(\extension_loaded('suhosin') || @\ini_get('suhosin.get.max_value_length') ? 'on' : 'off'). - '][APC:'.(\MailSo\Base\Utils::FunctionExistsAndEnabled('apc_fetch') ? 'on' : 'off'). - '][MB:'.(\MailSo\Base\Utils::FunctionExistsAndEnabled('mb_convert_encoding') ? 'on' : 'off'). - '][PDO:'.$sPdo. - (\RainLoop\Utils::IsOwnCloud() ? '][cloud:true' : ''). - '][Streams:'.\implode(',', \stream_get_transports()). - ']'); - - $this->oLogger->Write( - '['.$oHttp->GetMethod().'] '.$oHttp->GetScheme().'://'.$oHttp->GetHost(false, false).$oHttp->GetServer('REQUEST_URI', ''), - \MailSo\Log\Enumerations\Type::NOTE, 'REQUEST'); - } - } - - return $this->oLogger; - } - - /** - * @return \MailSo\Log\Logger - */ - public function LoggerAuth() - { - if (null === $this->oLoggerAuth) - { - $this->oLoggerAuth = \MailSo\Log\Logger::NewInstance(false); - - if (!!$this->Config()->Get('logs', 'auth_logging', false)) - { - $sAuthLogFileFullPath = \APP_PRIVATE_DATA.'logs/'.$this->compileLogFileName( - $this->Config()->Get('logs', 'auth_logging_filename', '')); - - $sLogFileDir = \dirname($sAuthLogFileFullPath); - - if (!@is_dir($sLogFileDir)) - { - @mkdir($sLogFileDir, 0755, true); - } - - $this->oLoggerAuth->AddForbiddenType(\MailSo\Log\Enumerations\Type::MEMORY); - $this->oLoggerAuth->AddForbiddenType(\MailSo\Log\Enumerations\Type::TIME); - $this->oLoggerAuth->AddForbiddenType(\MailSo\Log\Enumerations\Type::TIME_DELTA); - - $oDriver = \MailSo\Log\Drivers\File::NewInstance($sAuthLogFileFullPath); - - $oDriver->DisableTimePrefix(); - $oDriver->DisableGuidPrefix(); - $oDriver->DisableTypedPrefix(); - - $this->oLoggerAuth->Add($oDriver); - } - } - - return $this->oLoggerAuth; - } - - /** - * @param \RainLoop\Model\Account $oAccount = null - * @param array $aAdditionalParams = array() - */ - public function LoggerAuthHelper($oAccount = null, $aAdditionalParams = array()) - { - $sLine = $this->Config()->Get('logs', 'auth_logging_format', ''); - if (!empty($sLine)) - { - $this->LoggerAuth()->Write($this->compileLogParams($sLine, $oAccount, false, $aAdditionalParams)); - } - } - - /** - * @return string - */ - private function getAdminToken() - { - $sRand = \MailSo\Base\Utils::Md5Rand(); - if (!$this->Cacher(null, true)->Set(\RainLoop\KeyPathHelper::SessionAdminKey($sRand), \time())) - { - $this->oLogger->Write('Cannot store an admin token', - \MailSo\Log\Enumerations\Type::WARNING); - - $sRand = ''; - } - - return '' === $sRand ? '' : \RainLoop\Utils::EncodeKeyValuesQ(array('token', \md5(APP_SALT), $sRand)); - } - - /** - * @param bool $bThrowExceptionOnFalse = true - * - * @return bool - */ - public function IsAdminLoggined($bThrowExceptionOnFalse = true) - { - $bResult = false; - if ($this->Config()->Get('security', 'allow_admin_panel', true)) - { - $aAdminHash = \RainLoop\Utils::DecodeKeyValuesQ($this->getAdminAuthToken()); - if (!empty($aAdminHash[0]) && !empty($aAdminHash[1]) && !empty($aAdminHash[2]) && - 'token' === $aAdminHash[0] && \md5(APP_SALT) === $aAdminHash[1] && - '' !== $this->Cacher(null, true)->Get(\RainLoop\KeyPathHelper::SessionAdminKey($aAdminHash[2]), '') - ) - { - $bResult = true; - } - } - - if (!$bResult && $bThrowExceptionOnFalse) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::AuthError); - } - - return $bResult; - } - - /** - * @param string $sTo - */ - public function SetMailtoRequest($sTo) - { - if (!empty($sTo)) - { - \RainLoop\Utils::SetCookie(self::AUTH_MAILTO_TOKEN_KEY, - \RainLoop\Utils::EncodeKeyValuesQ(array( - 'Time' => \microtime(true), - 'MailTo' => 'MailTo', - 'To' => $sTo - )), 0); - } - } - - /** - * @param string $sEmail - * @param string $sLogin - * @param string $sPassword - * @param string $sSignMeToken = '' - * @param bool $bThrowProvideException = false - * - * @return \RainLoop\Model\Account|null - */ - public function LoginProvide($sEmail, $sLogin, $sPassword, $sSignMeToken = '', $bThrowProvideException = false) - { - $oAccount = null; - if (0 < \strlen($sEmail) && 0 < \strlen($sLogin) && 0 < \strlen($sPassword)) - { - $oDomain = $this->DomainProvider()->Load(\MailSo\Base\Utils::GetDomainFromEmail($sEmail), true); - if ($oDomain instanceof \RainLoop\Model\Domain) - { - if ($oDomain->ValidateWhiteList($sEmail, $sLogin)) - { - $oAccount = \RainLoop\Model\Account::NewInstance($sEmail, $sLogin, $sPassword, $oDomain, $sSignMeToken); - $this->Plugins()->RunHook('filter.account', array(&$oAccount)); - - if ($bThrowProvideException && !($oAccount instanceof \RainLoop\Model\Account)) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::AuthError); - } - } - else if ($bThrowProvideException) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::AccountNotAllowed); - } - } - else if ($bThrowProvideException) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::DomainNotAllowed); - } - } - - return $oAccount; - } - - /** - * @param string $sToken - * @param bool $bThrowExceptionOnFalse = true - * @param bool $bValidateShortToken = true - * @param bool $bQ = false - * - * @return \RainLoop\Model\Account|bool - * @throws \RainLoop\Exceptions\ClientException - */ - public function GetAccountFromCustomToken($sToken, $bThrowExceptionOnFalse = true, $bValidateShortToken = true, $bQ = false) - { - $oResult = false; - if (!empty($sToken)) - { - $aAccountHash = $bQ ? \RainLoop\Utils::DecodeKeyValuesQ($sToken) : \RainLoop\Utils::DecodeKeyValues($sToken); - if (!empty($aAccountHash[0]) && 'token' === $aAccountHash[0] && // simple token validation - 8 <= \count($aAccountHash) && // length checking - !empty($aAccountHash[7]) && // does short token exist - (!$bValidateShortToken || \RainLoop\Utils::GetShortToken() === $aAccountHash[7] || // check short token if needed - (isset($aAccountHash[10]) && 0 < $aAccountHash[10] && \time() < $aAccountHash[10])) - ) - { - $oAccount = $this->LoginProvide($aAccountHash[1], $aAccountHash[2], $aAccountHash[3], - empty($aAccountHash[5]) ? '' : $aAccountHash[5], $bThrowExceptionOnFalse); - - if ($oAccount instanceof \RainLoop\Model\Account) - { - if (!empty($aAccountHash[8]) && !empty($aAccountHash[9])) // init proxy user/password - { - $oAccount->SetProxyAuthUser($aAccountHash[8]); - $oAccount->SetProxyAuthPassword($aAccountHash[9]); - } - - $this->Logger()->AddSecret($oAccount->Password()); - $this->Logger()->AddSecret($oAccount->ProxyAuthPassword()); - - $oAccount->SetParentEmail($aAccountHash[6]); - $oResult = $oAccount; - } - } - else if ($bThrowExceptionOnFalse) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::AuthError); - } - } - - if ($bThrowExceptionOnFalse && !($oResult instanceof \RainLoop\Model\Account)) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::AuthError); - } - - return $oResult; - } - - /** - * @return \RainLoop\Model\Account|bool - */ - public function GetAccountFromSignMeToken() - { - $oAccount = false; - - $sSignMeToken = \RainLoop\Utils::GetCookie(\RainLoop\Actions::AUTH_SIGN_ME_TOKEN_KEY, ''); - if (!empty($sSignMeToken)) - { - $aTokenData = \RainLoop\Utils::DecodeKeyValuesQ($sSignMeToken); - if (\is_array($aTokenData) && !empty($aTokenData['e']) && !empty($aTokenData['t'])) - { - $sTokenSettings = $this->StorageProvider()->Get($aTokenData['e'], - \RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG, - 'sign_me' - ); - - if (!empty($sTokenSettings)) - { - $aSignMeData = \RainLoop\Utils::DecodeKeyValuesQ($sTokenSettings); - if (\is_array($aSignMeData) && - !empty($aSignMeData['AuthToken']) && - !empty($aSignMeData['SignMetToken']) && - $aSignMeData['SignMetToken'] === $aTokenData['t']) - { - $oAccount = $this->GetAccountFromCustomToken($aSignMeData['AuthToken'], false, false, true); - } - } - } - } - else - { - \RainLoop\Utils::ClearCookie(\RainLoop\Actions::AUTH_SIGN_ME_TOKEN_KEY); - } - - return $oAccount; - } - - /** - * @param bool $bThrowExceptionOnFalse = true - * - * @return \RainLoop\Model\Account|bool - * @throws \RainLoop\Exceptions\ClientException - */ - public function getAccountFromToken($bThrowExceptionOnFalse = true) - { - return $this->GetAccountFromCustomToken($this->getLocalAuthToken(), $bThrowExceptionOnFalse, true, true); - } - - /** - * @return bool - */ - public function IsOpen() - { - return !$this->PremProvider(); - } - - /** - * @param bool $bAdmin = false - * @param bool $bMobile = false - * @param bool $bMobileDevice = false - * - * @return array - */ - public function AppDataSystem($bAdmin = false, $bMobile = false, $bMobileDevice = false) - { - $oConfig = $this->Config(); - - $aAttachmentsActions = array(); - if ($this->GetCapa(false, $bMobile, \RainLoop\Enumerations\Capa::ATTACHMENTS_ACTIONS)) - { - if (!!\class_exists('ZipArchive')) - { - $aAttachmentsActions[] = 'zip'; - } - - if (\RainLoop\Utils::IsOwnCloudLoggedIn() && \class_exists('OCP\Files')) - { - $aAttachmentsActions[] = 'owncloud'; - } - - if ($oConfig->Get('social', 'dropbox_enable', false) && 0 < \strlen(\trim($oConfig->Get('social', 'dropbox_api_key', '')))) - { - $aAttachmentsActions[] = 'dropbox'; - } - } - - return \array_merge(array( - 'version' => APP_VERSION, - 'admin' => $bAdmin, - 'mobile' => $bMobile, - 'mobileDevice' => $bMobileDevice, - 'webPath' => \RainLoop\Utils::WebPath(), - 'webVersionPath' => \RainLoop\Utils::WebVersionPath(), - 'token' => $oConfig->Get('security', 'csrf_protection', false) ? \RainLoop\Utils::GetCsrfToken() : '', - 'inIframe' => (bool) $oConfig->Get('labs', 'in_iframe', false), - 'allowHtmlEditorSourceButton' => (bool) $oConfig->Get('labs', 'allow_html_editor_source_button', false), - 'allowHtmlEditorBitiButtons' => (bool) $oConfig->Get('labs', 'allow_html_editor_biti_buttons', false), - 'allowCtrlEnterOnCompose' => (bool) $oConfig->Get('labs', 'allow_ctrl_enter_on_compose', false), - 'customLoginLink' => $oConfig->Get('labs', 'custom_login_link', ''), - 'customLogoutLink' => $oConfig->Get('labs', 'custom_logout_link', ''), - 'forgotPasswordLinkUrl' => \trim($oConfig->Get('login', 'forgot_password_link_url', '')), - 'registrationLinkUrl' => \trim($oConfig->Get('login', 'registration_link_url', '')), - 'hideSubmitButton' => (bool) $oConfig->Get('login', 'hide_submit_button', true), - 'jsHash' => \md5(\RainLoop\Utils::GetConnectionToken()), - 'useImapThread' => (bool) $oConfig->Get('labs', 'use_imap_thread', false), - 'useImapSubscribe' => (bool) $oConfig->Get('labs', 'use_imap_list_subscribe', true), - 'allowAppendMessage' => (bool) $oConfig->Get('labs', 'allow_message_append', false), - 'materialDesign' => (bool) $oConfig->Get('labs', 'use_material_design', true), - 'folderSpecLimit' => (int) $oConfig->Get('labs', 'folders_spec_limit', 50), - 'faviconStatus' => (bool) $oConfig->Get('labs', 'favicon_status', true), - 'allowCmdInterface' => (bool) $oConfig->Get('labs', 'allow_cmd', false), - 'useNativeScrollbars' => (bool) $oConfig->Get('interface', 'use_native_scrollbars', false), - 'listPermanentFiltered' => '' !== \trim(\RainLoop\Api::Config()->Get('labs', 'imap_message_list_permanent_filter', '')), - 'themes' => $this->GetThemes($bMobile, false), - 'languages' => $this->GetLanguages(false), - 'languagesAdmin' => $this->GetLanguages(true), - 'appVersionType' => APP_VERSION_TYPE, - 'attachmentsActions' => $aAttachmentsActions - ), $bAdmin ? array( - 'adminHostUse' => '' !== $oConfig->Get('security', 'admin_panel_host', ''), - 'adminPath' => \strtolower($oConfig->Get('security', 'admin_panel_key', 'admin')), - 'allowAdminPanel' => (bool) $oConfig->Get('security', 'allow_admin_panel', true), - ) : array()); - } - - /** - * @param bool $bAdmin - * @param bool $bMobile = false - * @param string $sAuthAccountHash = '' - * - * @return array - */ - public function AppData($bAdmin, $bMobile = false, $bMobileDevice = false, $sAuthAccountHash = '') - { - if (0 < \strlen($sAuthAccountHash) && \preg_match('/[^_\-\.a-zA-Z0-9]/', $sAuthAccountHash)) - { - $sAuthAccountHash = ''; - } - - $oAccount = null; - $oConfig = $this->Config(); - -/* -required by Index.html and rl.js: -NewThemeLink IncludeCss LoadingDescriptionEsc TemplatesLink LangLink IncludeBackground PluginsLink AuthAccountHash -*/ - - $aResult = array( - 'Auth' => false, - 'AccountHash' => '', - 'AccountSignMe' => false, - 'AuthAccountHash' => '', - 'MailToEmail' => '', - 'Email' => '', - 'DevEmail' => '', - 'DevPassword' => '', - 'Title' => $oConfig->Get('webmail', 'title', 'RainLoop Webmail'), - 'LoadingDescription' => $oConfig->Get('webmail', 'loading_description', 'RainLoop'), - 'LoadingDescriptionEsc' => 'RainLoop', - 'FaviconUrl' => $oConfig->Get('webmail', 'favicon_url', ''), - 'LoginDescription' => '', - 'LoginPowered' => true, - 'LoginLogo' => '', - 'LoginBackground' => '', - 'LoginCss' => '', - 'UserLogo' => '', - 'UserLogoTitle' => '', - 'UserLogoMessage' => '', - 'UserCss' => '', - 'WelcomePageUrl' => '', - 'WelcomePageDisplay' => 'none', - 'IncludeCss' => '', - 'IncludeBackground' => '', - 'LoginDefaultDomain' => $oConfig->Get('login', 'default_domain', ''), - 'DetermineUserLanguage' => (bool) $oConfig->Get('login', 'determine_user_language', true), - 'DetermineUserDomain' => (bool) $oConfig->Get('login', 'determine_user_domain', false), - 'UseLoginWelcomePage' => (bool) $oConfig->Get('login', 'welcome_page', false), - 'StartupUrl' => \trim(\ltrim(\trim($oConfig->Get('labs', 'startup_url', '')), '#/')), - 'SieveAllowFileintoInbox' => (bool) $oConfig->Get('labs', 'sieve_allow_fileinto_inbox', false), - 'ContactsIsAllowed' => false, - 'ChangePasswordIsAllowed' => false, - 'RequireTwoFactor' => false, - 'Community' => true, - 'PremType' => false, - 'Admin' => array(), - 'Capa' => array(), - 'Plugins' => array(), - 'System' => $this->AppDataSystem($bAdmin, $bMobile, $bMobileDevice) - ); - - if (0 < \strlen($sAuthAccountHash)) - { - $aResult['AuthAccountHash'] = $sAuthAccountHash; - } - - $oPremProvider = $this->PremProvider(); - if ($oPremProvider) - { - $oPremProvider->PopulateAppData($aResult); - } - - if ('' !== $aResult['LoadingDescription'] && 'RainLoop' !== $aResult['LoadingDescription']) - { - $aResult['LoadingDescriptionEsc'] = @\htmlspecialchars($aResult['LoadingDescription'], ENT_QUOTES|ENT_IGNORE, 'UTF-8'); - } - - $oSettings = null; - - if (!$bAdmin) - { - $oAccount = $this->getAccountFromToken(false); - if ($oAccount instanceof \RainLoop\Model\Account) - { - $aResult['IncludeCss'] = $aResult['UserCss']; - - $oAddressBookProvider = $this->AddressBookProvider($oAccount); - - $aResult['Auth'] = true; - $aResult['Email'] = $oAccount->Email(); - $aResult['IncLogin'] = $oAccount->IncLogin(); - $aResult['OutLogin'] = $oAccount->OutLogin(); - $aResult['AccountHash'] = $oAccount->Hash(); - $aResult['AccountSignMe'] = $oAccount->SignMe(); - $aResult['ChangePasswordIsAllowed'] = $this->ChangePasswordProvider()->PasswordChangePossibility($oAccount); - $aResult['ContactsIsAllowed'] = $oAddressBookProvider->IsActive(); - $aResult['ContactsSyncIsAllowed'] = (bool) $oConfig->Get('contacts', 'allow_sync', false); - $aResult['ContactsSyncInterval'] = (int) $oConfig->Get('contacts', 'sync_interval', 20); - - $aResult['EnableContactsSync'] = false; - $aResult['ContactsSyncUrl'] = ''; - $aResult['ContactsSyncUser'] = ''; - $aResult['ContactsSyncPassword'] = ''; - - if ($aResult['ContactsIsAllowed'] && $aResult['ContactsSyncIsAllowed']) - { - $mData = $this->getContactsSyncData($oAccount); - if (\is_array($mData)) - { - $aResult['EnableContactsSync'] = isset($mData['Enable']) ? !!$mData['Enable'] : false; - $aResult['ContactsSyncUrl'] = isset($mData['Url']) ? \trim($mData['Url']) : ''; - $aResult['ContactsSyncUser'] = isset($mData['User']) ? \trim($mData['User']) : ''; - $aResult['ContactsSyncPassword'] = APP_DUMMY; - } - } - - if ($aResult['AccountSignMe']) - { - $sToken = \RainLoop\Utils::GetCookie(self::AUTH_MAILTO_TOKEN_KEY, null); - if (null !== $sToken) - { - \RainLoop\Utils::ClearCookie(self::AUTH_MAILTO_TOKEN_KEY); - - $mMailToData = \RainLoop\Utils::DecodeKeyValuesQ($sToken); - if (\is_array($mMailToData) && !empty($mMailToData['MailTo']) && - 'MailTo' === $mMailToData['MailTo'] && !empty($mMailToData['To'])) - { - $aResult['MailToEmail'] = $mMailToData['To']; - } - } - } - - $oSettings = $this->SettingsProvider()->Load($oAccount); - - if (!$oAccount->IsAdditionalAccount() && !empty($aResult['WelcomePageUrl']) && - ('once' === $aResult['WelcomePageDisplay'] || 'always' === $aResult['WelcomePageDisplay'])) - { - if ('once' === $aResult['WelcomePageDisplay']) - { - if ($aResult['WelcomePageUrl'] === $oSettings->GetConf('LastWelcomePage', '')) - { - $aResult['WelcomePageUrl'] = ''; - $aResult['WelcomePageDisplay'] = ''; - } - } - } - else - { - $aResult['WelcomePageUrl'] = ''; - $aResult['WelcomePageDisplay'] = ''; - } - - if (!empty($aResult['StartupUrl'])) - { - $aResult['StartupUrl'] = $this->compileLogParams($aResult['StartupUrl'], $oAccount, true); - } - - if (!empty($aResult['UserIframeMessage'])) - { - $aResult['UserIframeMessage'] = $this->compileLogParams($aResult['UserIframeMessage'], $oAccount, true); - } - } - else - { - $oAccount = null; - - $aResult['IncludeBackground'] = $aResult['LoginBackground']; - $aResult['IncludeCss'] = $aResult['LoginCss']; - - $aResult['DevEmail'] = $oConfig->Get('labs', 'dev_email', ''); - $aResult['DevPassword'] = $oConfig->Get('labs', 'dev_password', ''); - - $aResult['WelcomePageUrl'] = ''; - $aResult['WelcomePageDisplay'] = ''; - - $aResult['StartupUrl'] = ''; - - if (empty($aResult['AdditionalLoginError'])) - { - $aResult['AdditionalLoginError'] = $this->GetSpecLogoutCustomMgsWithDeletion(); - } - } - - $aResult['AllowGoogleSocial'] = (bool) $oConfig->Get('social', 'google_enable', false); - $aResult['AllowGoogleSocialAuth'] = (bool) $oConfig->Get('social', 'google_enable_auth', true); - $aResult['AllowGoogleSocialAuthFast'] = (bool) $oConfig->Get('social', 'google_enable_auth_fast', true); - $aResult['AllowGoogleSocialDrive'] = (bool) $oConfig->Get('social', 'google_enable_drive', true); - $aResult['AllowGoogleSocialPreview'] = (bool) $oConfig->Get('social', 'google_enable_preview', true); - - $aResult['GoogleClientID'] = \trim($oConfig->Get('social', 'google_client_id', '')); - $aResult['GoogleApiKey'] = \trim($oConfig->Get('social', 'google_api_key', '')); - - if (!$aResult['AllowGoogleSocial'] || ($aResult['AllowGoogleSocial'] && ( - '' === \trim($oConfig->Get('social', 'google_client_id', '')) || '' === \trim($oConfig->Get('social', 'google_client_secret', ''))))) - { - $aResult['AllowGoogleSocialAuth'] = false; - $aResult['AllowGoogleSocialAuthFast'] = false; - $aResult['AllowGoogleSocialDrive'] = false; - $aResult['GoogleClientID'] = ''; - $aResult['GoogleApiKey'] = ''; - } - - if (!$aResult['AllowGoogleSocial']) - { - $aResult['AllowGoogleSocialPreview'] = false; - } - - if ($aResult['AllowGoogleSocial'] && - !$aResult['AllowGoogleSocialAuth'] && !$aResult['AllowGoogleSocialAuthFast'] && - !$aResult['AllowGoogleSocialDrive'] && !$aResult['AllowGoogleSocialPreview']) - { - $aResult['AllowGoogleSocial'] = false; - } - - $aResult['AllowFacebookSocial'] = (bool) $oConfig->Get('social', 'fb_enable', false); - if ($aResult['AllowFacebookSocial'] && ( - '' === \trim($oConfig->Get('social', 'fb_app_id', '')) || '' === \trim($oConfig->Get('social', 'fb_app_secret', '')))) - { - $aResult['AllowFacebookSocial'] = false; - } - - $aResult['AllowTwitterSocial'] = (bool) $oConfig->Get('social', 'twitter_enable', false); - if ($aResult['AllowTwitterSocial'] && ( - '' === \trim($oConfig->Get('social', 'twitter_consumer_key', '')) || '' === \trim($oConfig->Get('social', 'twitter_consumer_secret', '')))) - { - $aResult['AllowTwitterSocial'] = false; - } - - $aResult['AllowDropboxSocial'] = (bool) $oConfig->Get('social', 'dropbox_enable', false); - $aResult['DropboxApiKey'] = \trim($oConfig->Get('social', 'dropbox_api_key', '')); - - if (!$aResult['AllowDropboxSocial']) - { - $aResult['DropboxApiKey'] = ''; - } - else if (0 === strlen($aResult['DropboxApiKey'])) - { - $aResult['AllowDropboxSocial'] = false; - } - - $aResult['Capa'] = $this->Capa(false, $bMobile, $oAccount); - - if ($aResult['Auth'] && !$aResult['RequireTwoFactor']) - { - if ($this->GetCapa(false, $bMobile, \RainLoop\Enumerations\Capa::TWO_FACTOR, $oAccount) && - $this->GetCapa(false, $bMobile, \RainLoop\Enumerations\Capa::TWO_FACTOR_FORCE, $oAccount) && - $this->TwoFactorAuthProvider()->IsActive()) - { - $aData = $this->getTwoFactorInfo($oAccount, true); - - $aResult['RequireTwoFactor'] = !$aData || - !isset($aData['User'], $aData['IsSet'], $aData['Enable']) || - !($aData['IsSet'] && $aData['Enable']); - } - } - } - else - { - $aResult['Auth'] = $this->IsAdminLoggined(false); - if ($aResult['Auth']) - { - $aResult['AdminDomain'] = APP_SITE; - $aResult['AdminLogin'] = (string) $oConfig->Get('security', 'admin_login', ''); - $aResult['UseTokenProtection'] = (bool) $oConfig->Get('security', 'csrf_protection', true); - $aResult['EnabledPlugins'] = (bool) $oConfig->Get('plugins', 'enable', false); - - $aResult['VerifySslCertificate'] = (bool) $oConfig->Get('ssl', 'verify_certificate', false); - $aResult['AllowSelfSigned'] = (bool) $oConfig->Get('ssl', 'allow_self_signed', true); - - $aDrivers = \class_exists('PDO') ? \PDO::getAvailableDrivers() : null; - $aResult['MySqlIsSupported'] = \is_array($aDrivers) ? \in_array('mysql', $aDrivers) : false; - $aResult['SQLiteIsSupported'] = \is_array($aDrivers) ? \in_array('sqlite', $aDrivers) : false; - $aResult['PostgreSqlIsSupported'] = \is_array($aDrivers) ? \in_array('pgsql', $aDrivers) : false; - - $aResult['ContactsEnable'] = (bool) $oConfig->Get('contacts', 'enable', false); - $aResult['ContactsSync'] = (bool) $oConfig->Get('contacts', 'allow_sync', false); - $aResult['ContactsPdoType'] = (string) $this->ValidateContactPdoType(\trim($this->Config()->Get('contacts', 'type', 'sqlite'))); - $aResult['ContactsPdoDsn'] = (string) $oConfig->Get('contacts', 'pdo_dsn', ''); - $aResult['ContactsPdoType'] = (string) $oConfig->Get('contacts', 'type', ''); - $aResult['ContactsPdoUser'] = (string) $oConfig->Get('contacts', 'pdo_user', ''); - $aResult['ContactsPdoPassword'] = (string) APP_DUMMY; - - $aResult['AllowGoogleSocial'] = (bool) $oConfig->Get('social', 'google_enable', false); - $aResult['AllowGoogleSocialAuth'] = (bool) $oConfig->Get('social', 'google_enable_auth', true); - $aResult['AllowGoogleSocialAuthFast'] = (bool) $oConfig->Get('social', 'google_enable_auth_fast', true); - $aResult['AllowGoogleSocialDrive'] = (bool) $oConfig->Get('social', 'google_enable_drive', true); - $aResult['AllowGoogleSocialPreview'] = (bool) $oConfig->Get('social', 'google_enable_preview', true); - - $aResult['GoogleClientID'] = (string) $oConfig->Get('social', 'google_client_id', ''); - $aResult['GoogleClientSecret'] = (string) $oConfig->Get('social', 'google_client_secret', ''); - $aResult['GoogleApiKey'] = (string) $oConfig->Get('social', 'google_api_key', ''); - - $aResult['AllowFacebookSocial'] = (bool) $oConfig->Get('social', 'fb_enable', false); - $aResult['FacebookAppID'] = (string) $oConfig->Get('social', 'fb_app_id', ''); - $aResult['FacebookAppSecret'] = (string) $oConfig->Get('social', 'fb_app_secret', ''); - - $aResult['AllowTwitterSocial'] = (bool) $oConfig->Get('social', 'twitter_enable', false); - $aResult['TwitterConsumerKey'] = (string) $oConfig->Get('social', 'twitter_consumer_key', ''); - $aResult['TwitterConsumerSecret'] = (string) $oConfig->Get('social', 'twitter_consumer_secret', ''); - - $aResult['AllowDropboxSocial'] = (bool) $oConfig->Get('social', 'dropbox_enable', false); - $aResult['DropboxApiKey'] = (string) $oConfig->Get('social', 'dropbox_api_key', ''); - - $aResult['SubscriptionEnabled'] = (bool) \MailSo\Base\Utils::ValidateDomain($aResult['AdminDomain'], true); -// || \MailSo\Base\Utils::ValidateIP($aResult['AdminDomain']); - - $aResult['WeakPassword'] = (bool) $oConfig->ValidatePassword('12345'); - $aResult['CoreAccess'] = (bool) $this->rainLoopCoreAccess(); - - $aResult['PhpUploadSizes'] = array( - 'upload_max_filesize' => \ini_get('upload_max_filesize'), - 'post_max_size' => \ini_get('post_max_size') - ); - } - - $aResult['Capa'] = $this->Capa(true, $bMobile); - } - - $aResult['SupportedFacebookSocial'] = (bool) \version_compare(PHP_VERSION, '5.4.0', '>='); - if (!$aResult['SupportedFacebookSocial']) - { - $aResult['AllowFacebookSocial'] = false; - $aResult['FacebookAppID'] = ''; - $aResult['FacebookAppSecret'] = ''; - } - - $aResult['ProjectHash'] = \md5($aResult['AccountHash'].APP_VERSION.$this->Plugins()->Hash()); - - $sLanguage = $oConfig->Get('webmail', 'language', 'en'); - $sLanguageAdmin = $oConfig->Get('webmail', 'language_admin', 'en'); - $sTheme = $oConfig->Get('webmail', 'theme', 'Default'); - - $aResult['NewMoveToFolder'] = (bool) $oConfig->Get('interface', 'new_move_to_folder_button', true); - $aResult['AllowLanguagesOnSettings'] = (bool) $oConfig->Get('webmail', 'allow_languages_on_settings', true); - $aResult['AllowLanguagesOnLogin'] = (bool) $oConfig->Get('login', 'allow_languages_on_login', true); - $aResult['AttachmentLimit'] = ((int) $oConfig->Get('webmail', 'attachment_size_limit', 10)) * 1024 * 1024; - $aResult['SignMe'] = (string) $oConfig->Get('login', 'sign_me_auto', \RainLoop\Enumerations\SignMeType::DEFAILT_OFF); - $aResult['UseLocalProxyForExternalImages'] = (bool) $oConfig->Get('labs', 'use_local_proxy_for_external_images', false); - - // user - $aResult['ShowImages'] = (bool) $oConfig->Get('defaults', 'show_images', false); - $aResult['MPP'] = (int) $oConfig->Get('webmail', 'messages_per_page', 25); - $aResult['SoundNotification'] = false; - $aResult['DesktopNotifications'] = false; - $aResult['Layout'] = (int) $oConfig->Get('defaults', 'view_layout', \RainLoop\Enumerations\Layout::SIDE_PREVIEW); - $aResult['EditorDefaultType'] = (string) $oConfig->Get('defaults', 'view_editor_type', ''); - $aResult['UseCheckboxesInList'] = (bool) $oConfig->Get('defaults', 'view_use_checkboxes', true); - $aResult['AutoLogout'] = (int) $oConfig->Get('defaults', 'autologout', 30); - $aResult['UseThreads'] = (bool) $oConfig->Get('defaults', 'mail_use_threads', false); - $aResult['AllowDraftAutosave'] = (bool) $oConfig->Get('defaults', 'allow_draft_autosave', true); - $aResult['ReplySameFolder'] = (bool) $oConfig->Get('defaults', 'mail_reply_same_folder', false); - $aResult['ContactsAutosave'] = (bool) $oConfig->Get('defaults', 'contacts_autosave', true); - $aResult['EnableTwoFactor'] = false; - $aResult['ParentEmail'] = ''; - $aResult['InterfaceAnimation'] = true; - $aResult['UserBackgroundName'] = ''; - $aResult['UserBackgroundHash'] = ''; - - if (!$bAdmin && $oAccount instanceof \RainLoop\Model\Account) - { - $aResult['ParentEmail'] = $oAccount->ParentEmail(); - - $oSettingsLocal = $this->SettingsProvider(true)->Load($oAccount); - - if ($oSettingsLocal instanceof \RainLoop\Settings) - { -// if ($this->GetCapa(false, $bMobile, \RainLoop\Enumerations\Capa::FOLDERS, $oAccount)) - - $aResult['SentFolder'] = (string) $oSettingsLocal->GetConf('SentFolder', ''); - $aResult['DraftFolder'] = (string) $oSettingsLocal->GetConf('DraftFolder', ''); - $aResult['SpamFolder'] = (string) $oSettingsLocal->GetConf('SpamFolder', ''); - $aResult['TrashFolder'] = (string) $oSettingsLocal->GetConf('TrashFolder', ''); - $aResult['ArchiveFolder'] = (string) $oSettingsLocal->GetConf('ArchiveFolder', ''); - $aResult['NullFolder'] = (string) $oSettingsLocal->GetConf('NullFolder', ''); - } - - if ($this->GetCapa(false, $bMobile, \RainLoop\Enumerations\Capa::SETTINGS, $oAccount)) - { - if ($oSettings instanceof \RainLoop\Settings) - { - if ($oConfig->Get('webmail', 'allow_languages_on_settings', true)) - { - $sLanguage = (string) $oSettings->GetConf('Language', $sLanguage); - } - - $aResult['EditorDefaultType'] = (string) $oSettings->GetConf('EditorDefaultType', $aResult['EditorDefaultType']); - $aResult['ShowImages'] = (bool) $oSettings->GetConf('ShowImages', $aResult['ShowImages']); - $aResult['ContactsAutosave'] = (bool) $oSettings->GetConf('ContactsAutosave', $aResult['ContactsAutosave']); - $aResult['MPP'] = (int) $oSettings->GetConf('MPP', $aResult['MPP']); - $aResult['SoundNotification'] = (bool) $oSettings->GetConf('SoundNotification', $aResult['SoundNotification']); - $aResult['DesktopNotifications'] = (bool) $oSettings->GetConf('DesktopNotifications', $aResult['DesktopNotifications']); - $aResult['UseCheckboxesInList'] = (bool) $oSettings->GetConf('UseCheckboxesInList', $aResult['UseCheckboxesInList']); - $aResult['AllowDraftAutosave'] = (bool) $oSettings->GetConf('AllowDraftAutosave', $aResult['AllowDraftAutosave']); - $aResult['AutoLogout'] = (int) $oSettings->GetConf('AutoLogout', $aResult['AutoLogout']); - $aResult['Layout'] = (int) $oSettings->GetConf('Layout', $aResult['Layout']); - - if (!$this->GetCapa(false, $bMobile, \RainLoop\Enumerations\Capa::AUTOLOGOUT, $oAccount)) - { - $aResult['AutoLogout'] = 0; - } - - if ($this->GetCapa(false, $bMobile, \RainLoop\Enumerations\Capa::USER_BACKGROUND, $oAccount)) - { - $aResult['UserBackgroundName'] = (string) $oSettings->GetConf('UserBackgroundName', $aResult['UserBackgroundName']); - $aResult['UserBackgroundHash'] = (string) $oSettings->GetConf('UserBackgroundHash', $aResult['UserBackgroundHash']); -// if (!empty($aResult['UserBackgroundName']) && !empty($aResult['UserBackgroundHash'])) -// { -// $aResult['IncludeBackground'] = './?/Raw/&q[]=/{{USER}}/UserBackground/&q[]=/'. -// $aResult['UserBackgroundHash'].'/'; -// } - } - - $aResult['EnableTwoFactor'] = (bool) $oSettings->GetConf('EnableTwoFactor', $aResult['EnableTwoFactor']); - } - - if ($oSettingsLocal instanceof \RainLoop\Settings) - { - $aResult['UseThreads'] = (bool) $oSettingsLocal->GetConf('UseThreads', $aResult['UseThreads']); - $aResult['ReplySameFolder'] = (bool) $oSettingsLocal->GetConf('ReplySameFolder', $aResult['ReplySameFolder']); - - if ($this->GetCapa(false, $bMobile, \RainLoop\Enumerations\Capa::THEMES, $oAccount)) - { - $sTheme = (string) $oSettingsLocal->GetConf('Theme', $sTheme); - } - } - } - } - - if (!$aResult['Auth']) - { - if (!$bAdmin) - { - if ($oConfig->Get('login', 'allow_languages_on_login', true) && - $oConfig->Get('login', 'determine_user_language', true)) - { - $sLanguage = $this->ValidateLanguage( - $this->detectUserLanguage($bAdmin), $sLanguage, false); - } - } - } - - $sTheme = $this->ValidateTheme($sTheme, $bMobile); - $sStaticCache = $this->StaticCache(); - - $aResult['Theme'] = $sTheme; - $aResult['NewThemeLink'] = $this->ThemeLink($sTheme, $bAdmin); - - $aResult['Language'] = $this->ValidateLanguage($sLanguage, '', false); - $aResult['LanguageAdmin'] = $this->ValidateLanguage($sLanguageAdmin, '', true); - - $aResult['UserLanguageRaw'] = $this->detectUserLanguage($bAdmin); - - $aResult['UserLanguage'] = $this->ValidateLanguage($aResult['UserLanguageRaw'], '', false, true); - $aResult['UserLanguageAdmin'] = $this->ValidateLanguage($aResult['UserLanguageRaw'], '', true, true); - - $aResult['PluginsLink'] = ''; - if (0 < $this->Plugins()->Count() && $this->Plugins()->HaveJs($bAdmin)) - { - $aResult['PluginsLink'] = './?/Plugins/0/'.($bAdmin ? 'Admin' : 'User').'/'.$sStaticCache.'/'; - } - - $aResult['LangLink'] = './?/Lang/0/'.($bAdmin ? 'Admin' : 'App').'/'. - ($bAdmin ? $aResult['LanguageAdmin'] : $aResult['Language']).'/'.$sStaticCache.'/'; - - $aResult['TemplatesLink'] = './?/Templates/0/'.($bAdmin ? 'Admin' : 'App').'/'.$sStaticCache.'/'; - - $bAppJsDebug = !!$this->Config()->Get('labs', 'use_app_debug_js', false); - - $aResult['StaticLibJsLink'] = $this->StaticPath('js/'.($bAppJsDebug ? '' : 'min/'). - 'libs'.($bAppJsDebug ? '' : '.min').'.js'); - $aResult['StaticAppJsLink'] = $this->StaticPath('js/'.($bAppJsDebug ? '' : 'min/'). - ($bAdmin ? 'admin' : 'app').($bAppJsDebug ? '' : '.min').'.js'); - - $aResult['StaticAppJsNextLink'] = $this->StaticPath('js/'.($bAdmin ? 'admin' : 'app').'.next.js'); - $aResult['StaticEditorJsLink'] = $this->StaticPath('ckeditor/ckeditor.js'); - - $aResult['EditorDefaultType'] = \in_array($aResult['EditorDefaultType'], array('Plain', 'Html', 'HtmlForced', 'PlainForced')) ? - $aResult['EditorDefaultType'] : 'Plain'; - - // IDN - $aResult['Email'] = \MailSo\Base\Utils::IdnToUtf8($aResult['Email']); - $aResult['ParentEmail'] = \MailSo\Base\Utils::IdnToUtf8($aResult['ParentEmail']); - $aResult['MailToEmail'] = \MailSo\Base\Utils::IdnToUtf8($aResult['MailToEmail']); - $aResult['DevEmail'] = \MailSo\Base\Utils::IdnToUtf8($aResult['DevEmail']); - - // Mobile override - if ($bMobile) - { - $aResult['Layout'] = \RainLoop\Enumerations\Layout::NO_PREVIW; - - $aResult['SoundNotification'] = false; - $aResult['DesktopNotifications'] = false; - $aResult['UseCheckboxesInList'] = true; - - $aResult['UserBackgroundName'] = ''; - $aResult['UserBackgroundHash'] = ''; - } - - $this->Plugins()->InitAppData($bAdmin, $aResult, $oAccount); - - return $aResult; - } - - /** - * @return array - */ - private function getUserLanguagesFromHeader() - { - $aResult = $aList = array(); - $sAcceptLang = \strtolower($this->Http()->GetServer('HTTP_ACCEPT_LANGUAGE', 'en')); - if (!empty($sAcceptLang) && \preg_match_all('/([a-z]{1,8}(?:-[a-z]{1,8})?)(?:;q=([0-9.]+))?/', $sAcceptLang, $aList)) - { - $aResult = \array_combine($aList[1], $aList[2]); - foreach ($aResult as $n => $v) - { - $aResult[$n] = $v ? $v : 1; - } - - \arsort($aResult, SORT_NUMERIC); - } - - return $aResult; - } - - /** - * @return string - */ - public function detectUserLanguage($bAdmin = false) - { - $sResult = ''; - $aLangs = $this->getUserLanguagesFromHeader(); - - foreach (\array_keys($aLangs) as $sLang) - { - $sLang = $this->ValidateLanguage($sLang, '', $bAdmin, true); - if (!empty($sLang)) - { - $sResult = $sLang; - break; - } - } - - return $sResult; - } - - /** - * @param int $iWait = 1 - * @param int $iDelay = 1 - */ - private function requestSleep($iWait = 1, $iDelay = 1) - { - if (0 < $iDelay && 0 < $iWait) - { - if ($iWait > \time() - APP_START_TIME) - { - \sleep($iDelay); - } - } - } - - private function loginErrorDelay() - { - $iDelay = (int) $this->Config()->Get('labs', 'login_fault_delay', 0); - if (0 < $iDelay) - { - $this->requestSleep(1, $iDelay); - } - } - - /** - * @param \RainLoop\Model\Account $oAccount - */ - public function AuthToken($oAccount) - { - if ($oAccount instanceof \RainLoop\Model\Account) - { - $this->SetAuthToken($oAccount); - - $aAccounts = $this->GetAccounts($oAccount); - if (\is_array($aAccounts) && isset($aAccounts[$oAccount->Email()])) - { - $aAccounts[$oAccount->Email()] = $oAccount->GetAuthToken(); - $this->SetAccounts($oAccount, $aAccounts); - } - } - } - - /** - * @param \RainLoop\Model\Account $oAccount - * @param bool $bAuthLog = false - * - * @throws \RainLoop\Exceptions\ClientException - */ - public function CheckMailConnection($oAccount, $bAuthLog = false) - { - try - { - $oAccount->IncConnectAndLoginHelper($this->Plugins(), $this->MailClient(), $this->Config()); - } - catch (\RainLoop\Exceptions\ClientException $oException) - { - throw $oException; - } - catch (\MailSo\Net\Exceptions\ConnectionException $oException) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::ConnectionError, $oException); - } - catch (\MailSo\Imap\Exceptions\LoginBadCredentialsException $oException) - { - if ($bAuthLog) - { - $this->LoggerAuthHelper($oAccount); - } - - if ($this->Config()->Get('labs', 'imap_show_login_alert', true)) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::AuthError, - $oException, $oException->getAlertFromStatus()); - } - else - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::AuthError, $oException); - } - } - catch (\Exception $oException) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::AuthError, $oException); - } - } - - /** - * @param string $sLogin - * @param bool $bAdmin = false - * @return array - */ - private function getAdditionalLogParamsByUserLogin($sLogin, $bAdmin = false) - { - $sHost = $bAdmin ? $this->Http()->GetHost(false, true, true) : \MailSo\Base\Utils::GetDomainFromEmail($sLogin); - return array( - '{imap:login}' => $sLogin, - '{imap:host}' => $sHost, - '{smtp:login}' => $sLogin, - '{smtp:host}' => $sHost, - '{user:email}' => $sLogin, - '{user:login}' => \MailSo\Base\Utils::GetAccountNameFromEmail($sLogin), - '{user:domain}' => $sHost, - ); - } - - /** - * @param string $sEmail - * @param string $sPassword - * @param string $sSignMeToken = '' - * @param string $sAdditionalCode = '' - * @param string $bAdditionalCodeSignMe = false - * @param string $bSkipTwoFactorAuth = false - * - * @return \RainLoop\Model\Account - * @throws \RainLoop\Exceptions\ClientException - */ - public function LoginProcess(&$sEmail, &$sPassword, $sSignMeToken = '', - $sAdditionalCode = '', $bAdditionalCodeSignMe = false, $bSkipTwoFactorAuth = false) - { - $sInputEmail = $sEmail; - - $this->Plugins()->RunHook('filter.login-credentials.step-1', array(&$sEmail, &$sPassword)); - - $sEmail = \MailSo\Base\Utils::Trim($sEmail); - if ($this->Config()->Get('login', 'login_lowercase', true)) - { - $sEmail = \MailSo\Base\Utils::StrToLowerIfAscii($sEmail); - } - - if (false === \strpos($sEmail, '@')) - { - $this->Logger()->Write('The email address "'.$sEmail.'" is not complete', \MailSo\Log\Enumerations\Type::INFO, 'LOGIN'); - - if (false === \strpos($sEmail, '@') && !!$this->Config()->Get('login', 'determine_user_domain', false)) - { - $sUserHost = \trim($this->Http()->GetHost(false, true, true)); - $this->Logger()->Write('Determined user domain: '.$sUserHost, \MailSo\Log\Enumerations\Type::INFO, 'LOGIN'); - - $bAdded = false; - - $iLimit = 14; - $aDomainParts = \explode('.', $sUserHost); - - $oDomainProvider = $this->DomainProvider(); - while (0 < \count($aDomainParts) && 0 < $iLimit) - { - $sLine = \trim(\implode('.', $aDomainParts), '. '); - - $oDomain = $oDomainProvider->Load($sLine, false); - if ($oDomain && $oDomain instanceof \RainLoop\Model\Domain) - { - $bAdded = true; - $this->Logger()->Write('Check "'.$sLine.'": OK ('.$sEmail.' > '.$sEmail.'@'.$sLine.')', - \MailSo\Log\Enumerations\Type::INFO, 'LOGIN'); - - $sEmail = $sEmail.'@'.$sLine; - break; - } - else - { - $this->Logger()->Write('Check "'.$sLine.'": NO', \MailSo\Log\Enumerations\Type::INFO, 'LOGIN'); - } - - \array_shift($aDomainParts); - $iLimit--; - } - - if (!$bAdded) - { - $sLine = $sUserHost; - $oDomain = $oDomainProvider->Load($sLine, true); - if ($oDomain && $oDomain instanceof \RainLoop\Model\Domain) - { - $bAdded = true; - $this->Logger()->Write('Check "'.$sLine.'" with wildcard: OK ('.$sEmail.' > '.$sEmail.'@'.$sLine.')', - \MailSo\Log\Enumerations\Type::INFO, 'LOGIN'); - - $sEmail = $sEmail.'@'.$sLine; - } - else - { - $this->Logger()->Write('Check "'.$sLine.'" with wildcard: NO', \MailSo\Log\Enumerations\Type::INFO, 'LOGIN'); - } - } - - if (!$bAdded) - { - $this->Logger()->Write('Domain was not found!', \MailSo\Log\Enumerations\Type::INFO, 'LOGIN'); - } - } - - $sDefDomain = \trim($this->Config()->Get('login', 'default_domain', '')); - if (false === \strpos($sEmail, '@') && 0 < \strlen($sDefDomain)) - { - $this->Logger()->Write('Default domain "'.$sDefDomain.'" was used. ('.$sEmail.' > '.$sEmail.'@'.$sDefDomain.')', - \MailSo\Log\Enumerations\Type::INFO, 'LOGIN'); - - $sEmail = $sEmail.'@'.$sDefDomain; - } - } - - $this->Plugins()->RunHook('filter.login-credentials.step-2', array(&$sEmail, &$sPassword)); - - if (false === \strpos($sEmail, '@') || 0 === \strlen($sPassword)) - { - $this->loginErrorDelay(); - - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::InvalidInputArgument); - } - - $this->Logger()->AddSecret($sPassword); - - $sLogin = $sEmail; - if ($this->Config()->Get('login', 'login_lowercase', true)) - { - $sLogin = \MailSo\Base\Utils::StrToLowerIfAscii($sLogin); - } - - $this->Plugins()->RunHook('filter.login-credentials', array(&$sEmail, &$sLogin, &$sPassword)); - - $this->Logger()->AddSecret($sPassword); - - $this->Plugins()->RunHook('event.login-pre-login-provide', array()); - - $oAccount = null; - - try - { - $oAccount = $this->LoginProvide($sEmail, $sLogin, $sPassword, $sSignMeToken, true); - - if (!($oAccount instanceof \RainLoop\Model\Account)) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::AuthError); - } - - $this->Plugins()->RunHook('event.login-post-login-provide', array(&$oAccount)); - - if (!($oAccount instanceof \RainLoop\Model\Account)) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::AuthError); - } - } - catch (\Exception $oException) - { - $this->loginErrorDelay(); - $this->LoggerAuthHelper($oAccount, $this->getAdditionalLogParamsByUserLogin($sInputEmail)); - throw $oException; - } - - // 2FA - if (!$bSkipTwoFactorAuth && $this->TwoFactorAuthProvider()->IsActive()) - { - $aData = $this->getTwoFactorInfo($oAccount); - if ($aData && isset($aData['IsSet'], $aData['Enable']) && !empty($aData['Secret']) && $aData['IsSet'] && $aData['Enable']) - { - $sSecretHash = \md5(APP_SALT.$aData['Secret'].\RainLoop\Utils::Fingerprint()); - $sSecretCookieHash = \RainLoop\Utils::GetCookie(self::AUTH_TFA_SIGN_ME_TOKEN_KEY, ''); - - if (empty($sSecretCookieHash) || $sSecretHash !== $sSecretCookieHash) - { - $sAdditionalCode = \trim($sAdditionalCode); - if (empty($sAdditionalCode)) - { - $this->Logger()->Write('TFA: Required Code for '.$oAccount->ParentEmailHelper().' account.'); - - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::AccountTwoFactorAuthRequired); - } - else - { - $this->Logger()->Write('TFA: Verify Code for '.$oAccount->ParentEmailHelper().' account.'); - - $bUseBackupCode = false; - if (6 < \strlen($sAdditionalCode) && !empty($aData['BackupCodes'])) - { - $aBackupCodes = \explode(' ', \trim(\preg_replace('/[^\d]+/', ' ', $aData['BackupCodes']))); - $bUseBackupCode = \in_array($sAdditionalCode, $aBackupCodes); - - if ($bUseBackupCode) - { - $this->removeBackupCodeFromTwoFactorInfo($oAccount->ParentEmailHelper(), $sAdditionalCode); - } - } - - if (!$bUseBackupCode && !$this->TwoFactorAuthProvider()->VerifyCode($aData['Secret'], $sAdditionalCode)) - { - $this->loginErrorDelay(); - - $this->LoggerAuthHelper($oAccount); - - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::AccountTwoFactorAuthError); - } - - if ($bAdditionalCodeSignMe) - { - \RainLoop\Utils::SetCookie(self::AUTH_TFA_SIGN_ME_TOKEN_KEY, $sSecretHash, - \time() + 60 * 60 * 24 * 14); - } - } - } - } - } - - try - { - $this->CheckMailConnection($oAccount, true); - } - catch (\Exception $oException) - { - $this->loginErrorDelay(); - - throw $oException; - } - - return $oAccount; - } - - /** - * @param string $sEmail - * - * @return string - */ - private function generateSignMeToken($sEmail) - { - return \MailSo\Base\Utils::Md5Rand(APP_SALT.$sEmail); - } - - /** - * @return array - * - * @throws \MailSo\Base\Exceptions\Exception - */ - public function DoLogin() - { - $sEmail = \MailSo\Base\Utils::Trim($this->GetActionParam('Email', '')); - $sPassword = $this->GetActionParam('Password', ''); - $sLanguage = $this->GetActionParam('Language', ''); - $bSignMe = '1' === (string) $this->GetActionParam('SignMe', '0'); - - $sAdditionalCode = $this->GetActionParam('AdditionalCode', ''); - $bAdditionalCodeSignMe = '1' === (string) $this->GetActionParam('AdditionalCodeSignMe', '0'); - - $oAccount = null; - - $this->Logger()->AddSecret($sPassword); - - if ('sleep@sleep.dev' === $sEmail && 0 < \strlen($sPassword) && - \is_numeric($sPassword) && $this->Config()->Get('debug', 'enable', false) && - 0 < (int) $sPassword && 30 > (int) $sPassword - ) - { - \sleep((int) $sPassword); - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::AuthError); - } - - try - { - $oAccount = $this->LoginProcess($sEmail, $sPassword, - $bSignMe ? $this->generateSignMeToken($sEmail) : '', - $sAdditionalCode, $bAdditionalCodeSignMe); - } - catch (\RainLoop\Exceptions\ClientException $oException) - { - if ($oException && - \RainLoop\Notifications::AccountTwoFactorAuthRequired === $oException->getCode()) - { - return $this->DefaultResponse(__FUNCTION__, true, array( - 'TwoFactorAuth' => true - )); - } - else - { - throw $oException; - } - } - - $this->AuthToken($oAccount); - - if ($oAccount && 0 < \strlen($sLanguage)) - { - $oSettings = $this->SettingsProvider()->Load($oAccount); - if ($oSettings) - { - $sLanguage = $this->ValidateLanguage($sLanguage); - $sCurrentLanguage = $oSettings->GetConf('Language', ''); - - if ($sCurrentLanguage !== $sLanguage) - { - $oSettings->SetConf('Language', $sLanguage); - $this->SettingsProvider()->Save($oAccount, $oSettings); - } - } - } - - return $this->TrueResponse(__FUNCTION__); - } - - /** - * @param \RainLoop\Model\Account $oAccount - * - * @return array - */ - public function GetAccounts($oAccount) - { - if ($this->GetCapa(false, false, \RainLoop\Enumerations\Capa::ADDITIONAL_ACCOUNTS, $oAccount)) - { - $sAccounts = $this->StorageProvider()->Get($oAccount, - \RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG, - 'accounts' - ); - - $aAccounts = array(); - if ('' !== $sAccounts && '{' === \substr($sAccounts, 0, 1)) - { - $aAccounts = @\json_decode($sAccounts, true); - } - - if (\is_array($aAccounts) && 0 < \count($aAccounts)) - { - if (1 === \count($aAccounts)) - { - $this->SetAccounts($oAccount, array()); - - } - else if (1 < \count($aAccounts)) - { - $sOrder = $this->StorageProvider()->Get($oAccount, - \RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG, - 'accounts_identities_order' - ); - - $aOrder = empty($sOrder) ? array() : @\json_decode($sOrder, true); - if (isset($aOrder['Accounts']) && \is_array($aOrder['Accounts']) && - 1 < \count($aOrder['Accounts'])) - { - $aAccounts = \array_merge(\array_flip($aOrder['Accounts']), $aAccounts); - - $aAccounts = \array_filter($aAccounts, function ($sHash) { - return 5 < \strlen($sHash); - }); - } - } - - return $aAccounts; - } - } - - $aAccounts = array(); - if (!$oAccount->IsAdditionalAccount()) - { - $aAccounts[$oAccount->Email()] = $oAccount->GetAuthToken(); - } - - return $aAccounts; - } - - /** - * @param \RainLoop\Model\Account $oAccount - * - * @return array - */ - public function GetTemplates($oAccount) - { - $aTemplates = array(); - if ($oAccount) - { - $aData = array(); - - $sData = $this->StorageProvider(true)->Get($oAccount, - \RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG, - 'templates' - ); - - if ('' !== $sData && '[' === \substr($sData, 0, 1)) - { - $aData = @\json_decode($sData, true); - } - - if (\is_array($aData) && 0 < \count($aData)) - { - foreach ($aData as $aItem) - { - $oItem = \RainLoop\Model\Template::NewInstance(); - $oItem->FromJSON($aItem); - - if ($oItem && $oItem->Validate()) - { - \array_push($aTemplates, $oItem); - } - } - } - - if (1 < \count($aTemplates)) - { - $sOrder = $this->StorageProvider()->Get($oAccount, - \RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG, - 'templates_order' - ); - - $aOrder = empty($sOrder) ? array() : @\json_decode($sOrder, true); - if (\is_array($aOrder) && 1 < \count($aOrder)) - { - \usort($aTemplates, function ($a, $b) use ($aOrder) { - return \array_search($a->Id(), $aOrder) < \array_search($b->Id(), $aOrder) ? -1 : 1; - }); - } - } - } - - return $aTemplates; - } - - /** - * @param \RainLoop\Model\Account $oAccount - * @param string $sID - * - * @return \RainLoop\Model\Identity - */ - public function GetTemplateByID($oAccount, $sID) - { - $aTemplates = $this->GetTemplates($oAccount); - if (\is_array($aTemplates)) - { - foreach ($aTemplates as $oIdentity) - { - if ($oIdentity && $sID === $oIdentity->Id()) - { - return $oIdentity; - } - } - } - - return isset($aTemplates[0]) ? $aTemplates[0] : null; - } - - /** - * @param \RainLoop\Model\Account $oAccount - * - * @return array - */ - public function GetIdentities($oAccount) - { - $bAllowIdentities = $this->GetCapa(false, false, - \RainLoop\Enumerations\Capa::IDENTITIES, $oAccount); - - $aIdentities = array(); - if ($oAccount) - { - $aSubIdentities = array(); - - $sData = $this->StorageProvider(true)->Get($oAccount, - \RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG, - 'identities' - ); - - if ('' !== $sData && '[' === \substr($sData, 0, 1)) - { - $aSubIdentities = @\json_decode($sData, true); - } - - $bHasAccountIdentity = false; - - if (\is_array($aSubIdentities) && 0 < \count($aSubIdentities)) - { - foreach ($aSubIdentities as $aItem) - { - $oItem = \RainLoop\Model\Identity::NewInstance(); - $oItem->FromJSON($aItem); - - if ($oItem && $oItem->Validate()) - { - if ($oItem->IsAccountIdentities()) - { - $oItem->SetEmail($oAccount->Email()); - $bHasAccountIdentity = true; - - \array_push($aIdentities, $oItem); - } - else if ($bAllowIdentities) - { - \array_push($aIdentities, $oItem); - } - } - } - } - - if (!$bHasAccountIdentity) - { - \array_unshift($aIdentities, - \RainLoop\Model\Identity::NewInstanceFromAccount($oAccount)); - } - - if (1 < \count($aIdentities) && $bAllowIdentities) - { - $sOrder = $this->StorageProvider()->Get($oAccount, - \RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG, - 'accounts_identities_order' - ); - - $aOrder = empty($sOrder) ? array() : @\json_decode($sOrder, true); - if (isset($aOrder['Identities']) && \is_array($aOrder['Identities']) && - 1 < \count($aOrder['Identities'])) - { - $aList = $aOrder['Identities']; - foreach ($aList as $iIndex => $sItem) - { - if ('' === $sItem) - { - $aList[$iIndex] = '---'; - } - } - - \usort($aIdentities, function ($a, $b) use ($aList) { - return \array_search($a->Id(true), $aList) < \array_search($b->Id(true), $aList) ? -1 : 1; - }); - } - } - } - - return $aIdentities; - } - - /** - * @param \RainLoop\Model\Account $oAccount - * @param string $sID - * @param bool $bFirstOnEmpty = false - * - * @return \RainLoop\Model\Identity - */ - public function GetIdentityByID($oAccount, $sID, $bFirstOnEmpty = false) - { - $aIdentities = $this->GetIdentities($oAccount); - - if (\is_array($aIdentities)) - { - foreach ($aIdentities as $oIdentity) - { - if ($oIdentity && $sID === $oIdentity->Id()) - { - return $oIdentity; - } - } - } - - return $bFirstOnEmpty && \is_array($aIdentities) && isset($aIdentities[0]) ? $aIdentities[0] : null; - } - /** - * @param \RainLoop\Model\Account $oAccount - * - * @return \RainLoop\Model\Identity - */ - public function GetAccountIdentity($oAccount) - { - return $this->GetIdentityByID($oAccount, '', true); - } - - /** - * @param \RainLoop\Model\Account $oAccount - * @param array $aAccounts = array() - * - * @return array - */ - public function SetAccounts($oAccount, $aAccounts = array()) - { - $sParentEmail = $oAccount->ParentEmailHelper(); - if (!\is_array($aAccounts) || 0 >= \count($aAccounts) || - (1 === \count($aAccounts) && !empty($aAccounts[$sParentEmail]))) - { - $this->StorageProvider()->Clear($oAccount, - \RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG, - 'accounts' - ); - } - else - { - $this->StorageProvider()->Put($oAccount, - \RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG, - 'accounts', - @\json_encode($aAccounts) - ); - } - } - - /** - * @param \RainLoop\Model\Account $oAccount - * @param array $aIdentities = array() - * - * @return array - */ - public function SetIdentities($oAccount, $aIdentities = array()) - { - $bAllowIdentities = $this->GetCapa(false, false, \RainLoop\Enumerations\Capa::IDENTITIES, $oAccount); - - $aResult = array(); - foreach ($aIdentities as $oItem) - { - if (!$bAllowIdentities && $oItem && !$oItem->IsAccountIdentities()) - { - continue; - } - - $aResult[] = $oItem->ToSimpleJSON(false); - } - - return $this->StorageProvider(true)->Put($oAccount, - \RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG, - 'identities', - @\json_encode($aResult) - ); - } - - /** - * @param \RainLoop\Model\Account $oAccount - * @param array $aTemplates = array() - * - * @return array - */ - public function SetTemplates($oAccount, $aTemplates = array()) - { - $aResult = array(); - foreach ($aTemplates as $oItem) - { - $aResult[] = $oItem->ToSimpleJSON(false); - } - - return $this->StorageProvider(true)->Put($oAccount, - \RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG, - 'templates', - @\json_encode($aResult) - ); - } - - /** - * @return array - * - * @throws \MailSo\Base\Exceptions\Exception - */ - public function DoFilters() - { - $oAccount = $this->getAccountFromToken(); - - if (!$this->GetCapa(false, false, \RainLoop\Enumerations\Capa::FILTERS, $oAccount)) - { - return $this->FalseResponse(__FUNCTION__); - } - - $aFakeFilters = null; - - $this->Plugins() - ->RunHook('filter.filters-fake', array($oAccount, &$aFakeFilters)) - ; - - if ($aFakeFilters) - { - return $this->DefaultResponse(__FUNCTION__, $aFakeFilters); - } - - return $this->DefaultResponse(__FUNCTION__, - $this->FiltersProvider()->Load($oAccount, $oAccount->DomainSieveAllowRaw())); - } - - /** - * @return array - * - * @throws \MailSo\Base\Exceptions\Exception - */ - public function DoFiltersSave() - { - $oAccount = $this->getAccountFromToken(); - - if (!$this->GetCapa(false, false, \RainLoop\Enumerations\Capa::FILTERS, $oAccount)) - { - return $this->FalseResponse(__FUNCTION__); - } - - $aIncFilters = $this->GetActionParam('Filters', array()); - - $sRaw = $this->GetActionParam('Raw', ''); - $bRawIsActive = '1' === (string) $this->GetActionParam('RawIsActive', '0'); - - $aFilters = array(); - foreach ($aIncFilters as $aFilter) - { - if ($aFilter) - { - $oFilter = new \RainLoop\Providers\Filters\Classes\Filter(); - if ($oFilter->FromJSON($aFilter)) - { - $aFilters[] = $oFilter; - } - } - } - - $this->Plugins() - ->RunHook('filter.filters-save', array($oAccount, &$aFilters, &$sRaw, &$bRawIsActive)) - ; - - return $this->DefaultResponse(__FUNCTION__, $this->FiltersProvider()->Save($oAccount, - $aFilters, $sRaw, $bRawIsActive)); - } - - /** - * @return array - * - * @throws \MailSo\Base\Exceptions\Exception - */ - public function DoAccountSetup() - { - $oAccount = $this->getAccountFromToken(); - - if (!$this->GetCapa(false, false, \RainLoop\Enumerations\Capa::ADDITIONAL_ACCOUNTS, $oAccount)) - { - return $this->FalseResponse(__FUNCTION__); - } - - $sParentEmail = $oAccount->ParentEmailHelper(); - - $aAccounts = $this->GetAccounts($oAccount); - if (!\is_array($aAccounts)) - { - $aAccounts = array(); - } - - $sEmail = \trim($this->GetActionParam('Email', '')); - $sPassword = $this->GetActionParam('Password', ''); - $bNew = '1' === (string) $this->GetActionParam('New', '1'); - - $sEmail = \MailSo\Base\Utils::IdnToAscii($sEmail, true); - if ($bNew && ($oAccount->Email() === $sEmail || $sParentEmail === $sEmail || isset($aAccounts[$sEmail]))) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::AccountAlreadyExists); - } - else if (!$bNew && !isset($aAccounts[$sEmail])) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::AccountDoesNotExist); - } - - $oNewAccount = $this->LoginProcess($sEmail, $sPassword, '', '', false, true); - $oNewAccount->SetParentEmail($sParentEmail); - - $aAccounts[$oNewAccount->Email()] = $oNewAccount->GetAuthToken(); - if (!$oAccount->IsAdditionalAccount()) - { - $aAccounts[$oAccount->Email()] = $oAccount->GetAuthToken(); - } - - $this->SetAccounts($oAccount, $aAccounts); - return $this->TrueResponse(__FUNCTION__); - } - - /** - * @return array - * - * @throws \MailSo\Base\Exceptions\Exception - */ - public function DoAccountDelete() - { - $oAccount = $this->getAccountFromToken(); - - if (!$this->GetCapa(false, false, \RainLoop\Enumerations\Capa::ADDITIONAL_ACCOUNTS, $oAccount)) - { - return $this->FalseResponse(__FUNCTION__); - } - - $sParentEmail = $oAccount->ParentEmailHelper(); - $sEmailToDelete = \trim($this->GetActionParam('EmailToDelete', '')); - $sEmailToDelete = \MailSo\Base\Utils::IdnToAscii($sEmailToDelete, true); - - $aAccounts = $this->GetAccounts($oAccount); - - if (0 < \strlen($sEmailToDelete) && $sEmailToDelete !== $sParentEmail && \is_array($aAccounts) && isset($aAccounts[$sEmailToDelete])) - { - unset($aAccounts[$sEmailToDelete]); - - $oAccountToChange = null; - if ($oAccount->Email() === $sEmailToDelete && !empty($aAccounts[$sParentEmail])) - { - $oAccountToChange = $this->GetAccountFromCustomToken($aAccounts[$sParentEmail], false, false); - if ($oAccountToChange) - { - $this->AuthToken($oAccountToChange); - } - } - - $this->SetAccounts($oAccount, $aAccounts); - return $this->TrueResponse(__FUNCTION__, array('Reload' => !!$oAccountToChange)); - } - - return $this->FalseResponse(__FUNCTION__); - } - - /** - * @return array - * - * @throws \MailSo\Base\Exceptions\Exception - */ - public function DoAttachmentsActions() - { - if (!$this->GetCapa(false, false, \RainLoop\Enumerations\Capa::ATTACHMENTS_ACTIONS)) - { - return $this->FalseResponse(__FUNCTION__); - } - - $oAccount = $this->initMailClientConnection(); - - $sAction = $this->GetActionParam('Do', ''); - $aHashes = $this->GetActionParam('Hashes', null); - - $mResult = false; - $bError = false; - $aData = false; - - if (\is_array($aHashes) && 0 < \count($aHashes)) - { - $aData = array(); - foreach ($aHashes as $sZipHash) - { - $aResult = $this->getMimeFileByHash($oAccount, $sZipHash); - if (\is_array($aResult) && !empty($aResult['FileHash'])) - { - $aData[] = $aResult; - } - else - { - $bError = true; - break; - } - } - } - - $oFilesProvider = $this->FilesProvider(); - if (!empty($sAction) && !$bError && \is_array($aData) && 0 < \count($aData) && - $oFilesProvider && $oFilesProvider->IsActive()) - { - $bError = false; - switch (\strtolower($sAction)) - { - case 'zip': - - if (\class_exists('ZipArchive')) - { - $sZipHash = \MailSo\Base\Utils::Md5Rand(); - $sZipFileName = $oFilesProvider->GenerateLocalFullFileName($oAccount, $sZipHash); - - if (!empty($sZipFileName)) - { - $oZip = new \ZipArchive(); - $oZip->open($sZipFileName, \ZIPARCHIVE::CREATE | \ZIPARCHIVE::OVERWRITE); - $oZip->setArchiveComment('RainLoop/'.APP_VERSION); - - foreach ($aData as $aItem) - { - $sFileName = (string) (isset($aItem['FileName']) ? $aItem['FileName'] : 'file.dat'); - $sFileHash = (string) (isset($aItem['FileHash']) ? $aItem['FileHash'] : ''); - - if (!empty($sFileHash)) - { - $sFullFileNameHash = $oFilesProvider->GetFileName($oAccount, $sFileHash); - if (!$oZip->addFile($sFullFileNameHash, $sFileName)) - { - $bError = true; - } - } - } - - if (!$bError) - { - $bError = !$oZip->close(); - } - else - { - $oZip->close(); - } - } - - foreach ($aData as $aItem) - { - $sFileHash = (string) (isset($aItem['FileHash']) ? $aItem['FileHash'] : ''); - if (!empty($sFileHash)) - { - $oFilesProvider->Clear($oAccount, $sFileHash); - } - } - - if (!$bError) - { - $mResult = array( - 'Files' => array(array( - 'FileName' => 'attachments.zip', - 'Hash' => \RainLoop\Utils::EncodeKeyValuesQ(array( - 'V' => APP_VERSION, - 'Account' => $oAccount ? \md5($oAccount->Hash()) : '', - 'FileName' => 'attachments.zip', - 'MimeType' => 'application/zip', - 'FileHash' => $sZipHash - )) - )) - ); - } - } - break; - - case 'owncloud': - - $mResult = false; - - if (\RainLoop\Utils::IsOwnCloudLoggedIn() && \class_exists('OCP\Files')) - { - $sSaveFolder = $this->Config()->Get('labs', 'owncloud_save_folder', ''); - if (empty($sSaveFolder)) - { - $sSaveFolder = 'Attachments'; - } - - $oFiles = \OCP\Files::getStorage('files'); - - if ($oFilesProvider && $oFiles && $oFilesProvider->IsActive() && - \method_exists($oFiles, 'file_put_contents')) - { - if (!$oFiles->is_dir($sSaveFolder)) - { - $oFiles->mkdir($sSaveFolder); - } - - $mResult = true; - foreach ($aData as $aItem) - { - $sSavedFileName = isset($aItem['FileName']) ? $aItem['FileName'] : 'file.dat'; - $sSavedFileHash = !empty($aItem['FileHash']) ? $aItem['FileHash'] : ''; - - if (!empty($sSavedFileHash)) - { - $fFile = $oFilesProvider->GetFile($oAccount, $sSavedFileHash, 'rb'); - if (\is_resource($fFile)) - { - $sSavedFileNameFull = \MailSo\Base\Utils::SmartFileExists($sSaveFolder.'/'.$sSavedFileName, function ($sPath) use ($oFiles) { - return $oFiles->file_exists($sPath); - }); - - if (!$oFiles->file_put_contents($sSavedFileNameFull, $fFile)) - { - $mResult = false; - } - - if (\is_resource($fFile)) - { - @\fclose($fFile); - } - } - } - } - } - } - - foreach ($aData as $aItem) - { - $sFileHash = (string) (isset($aItem['FileHash']) ? $aItem['FileHash'] : ''); - if (!empty($sFileHash)) - { - $oFilesProvider->Clear($oAccount, $sFileHash); - } - } - - break; - - case 'dropbox': - - $mResult = array( - 'ShortLife' => '_'.$this->GetShortLifeSpecAuthToken(), - 'Url' => \preg_replace('/\?(.*)$/', '', $this->Http()->GetFullUrl()), - 'Files' => array() - ); - - foreach ($aData as $aItem) - { - $mResult['Files'][] = array( - 'FileName' => isset($aItem['FileName']) ? $aItem['FileName'] : 'file.dat', - 'Hash' => \RainLoop\Utils::EncodeKeyValuesQ($aItem) - ); - } - - break; - } - } - else - { - $bError = true; - } - - $this->requestSleep(); - return $this->DefaultResponse(__FUNCTION__, $bError ? false : $mResult); - } - - /** - * @return array - * - * @throws \MailSo\Base\Exceptions\Exception - */ - public function DoIdentityUpdate() - { - $oAccount = $this->getAccountFromToken(); - - $oIdentity = \RainLoop\Model\Identity::NewInstance(); - if (!$oIdentity->FromJSON($this->GetActionParams(), true)) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::InvalidInputArgument); - } - - $aIdentities = $this->GetIdentities($oAccount); - - $bAdded = false; - $aIdentitiesForSave = array(); - foreach ($aIdentities as $oItem) - { - if ($oItem) - { - if ($oItem->Id() === $oIdentity->Id()) - { - $aIdentitiesForSave[] = $oIdentity; - $bAdded = true; - } - else - { - $aIdentitiesForSave[] = $oItem; - } - } - } - - if (!$bAdded) - { - $aIdentitiesForSave[] = $oIdentity; - } - - return $this->DefaultResponse(__FUNCTION__, $this->SetIdentities($oAccount, $aIdentitiesForSave)); - } - - /** - * @return array - * - * @throws \MailSo\Base\Exceptions\Exception - */ - public function DoIdentityDelete() - { - $oAccount = $this->getAccountFromToken(); - - if (!$this->GetCapa(false, false, \RainLoop\Enumerations\Capa::IDENTITIES, $oAccount)) - { - return $this->FalseResponse(__FUNCTION__); - } - - $sId = \trim($this->GetActionParam('IdToDelete', '')); - if (empty($sId)) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::UnknownError); - } - - $aNew = array(); - $aIdentities = $this->GetIdentities($oAccount); - - foreach ($aIdentities as $oItem) - { - if ($oItem && $sId !== $oItem->Id()) - { - $aNew[] = $oItem; - } - } - - return $this->DefaultResponse(__FUNCTION__, $this->SetIdentities($oAccount, $aNew)); - } - - /** - * @return array - * - * @throws \MailSo\Base\Exceptions\Exception - */ - public function DoTemplateSetup() - { - $oAccount = $this->getAccountFromToken(); - - if (!$this->GetCapa(false, false, \RainLoop\Enumerations\Capa::TEMPLATES, $oAccount)) - { - return $this->FalseResponse(__FUNCTION__); - } - - $oTemplate = \RainLoop\Model\Template::NewInstance(); - if (!$oTemplate->FromJSON($this->GetActionParams(), true)) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::InvalidInputArgument); - } - - if ('' === $oTemplate->Id()) - { - $oTemplate->GenerateID(); - } - - $aTemplatesForSave = array(); - $aTemplates = $this->GetTemplates($oAccount); - - - foreach ($aTemplates as $oItem) - { - if ($oItem && $oItem->Id() !== $oTemplate->Id()) - { - $aTemplatesForSave[] = $oItem; - } - } - - $aTemplatesForSave[] = $oTemplate; - - return $this->DefaultResponse(__FUNCTION__, $this->SetTemplates($oAccount, $aTemplatesForSave)); - } - - /** - * @return array - * - * @throws \MailSo\Base\Exceptions\Exception - */ - public function DoTemplateDelete() - { - $oAccount = $this->getAccountFromToken(); - - if (!$this->GetCapa(false, false, \RainLoop\Enumerations\Capa::TEMPLATES, $oAccount)) - { - return $this->FalseResponse(__FUNCTION__); - } - - $sId = \trim($this->GetActionParam('IdToDelete', '')); - if (empty($sId)) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::UnknownError); - } - - $aNew = array(); - $aTemplates = $this->GetTemplates($oAccount); - foreach ($aTemplates as $oItem) - { - if ($oItem && $sId !== $oItem->Id()) - { - $aNew[] = $oItem; - } - } - - return $this->DefaultResponse(__FUNCTION__, $this->SetTemplates($oAccount, $aNew)); - } - - /** - * @return array - * - * @throws \MailSo\Base\Exceptions\Exception - */ - public function DoTemplateGetByID() - { - $oAccount = $this->getAccountFromToken(); - - if (!$this->GetCapa(false, false, \RainLoop\Enumerations\Capa::TEMPLATES, $oAccount)) - { - return $this->FalseResponse(__FUNCTION__); - } - - $sId = \trim($this->GetActionParam('ID', '')); - if (empty($sId)) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::UnknownError); - } - - $oTemplate = false; - $aTemplates = $this->GetTemplates($oAccount); - - foreach ($aTemplates as $oItem) - { - if ($oItem && $sId === $oItem->Id()) - { - $oTemplate = $oItem; - break; - } - } - - $oTemplate->SetPopulateAlways(true); - return $this->DefaultResponse(__FUNCTION__, $oTemplate); - } - - /** - * @return array - * - * @throws \MailSo\Base\Exceptions\Exception - */ - public function DoAccountsAndIdentitiesSortOrder() - { - $oAccount = $this->getAccountFromToken(); - - $aAccounts = $this->GetActionParam('Accounts', null); - $aIdentities = $this->GetActionParam('Identities', null); - - if (!\is_array($aAccounts) && !\is_array($aIdentities)) - { - return $this->FalseResponse(__FUNCTION__); - } - - return $this->DefaultResponse(__FUNCTION__, $this->StorageProvider()->Put($oAccount, - \RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG, 'accounts_identities_order', - \json_encode(array( - 'Accounts' => \is_array($aAccounts) ? $aAccounts : array(), - 'Identities' => \is_array($aIdentities) ? $aIdentities : array() - )) - )); - } - - /** - * @return array - * - * @throws \MailSo\Base\Exceptions\Exception - */ - public function DoAccountsAndIdentities() - { - $oAccount = $this->getAccountFromToken(); - - $mAccounts = false; - - if ($this->GetCapa(false, false, \RainLoop\Enumerations\Capa::ADDITIONAL_ACCOUNTS, $oAccount)) - { - $mAccounts = $this->GetAccounts($oAccount); - $mAccounts = \array_keys($mAccounts); - - foreach ($mAccounts as $iIndex => $sName) - { - $mAccounts[$iIndex] = \MailSo\Base\Utils::IdnToUtf8($sName); - } - } - - return $this->DefaultResponse(__FUNCTION__, array( - 'Accounts' => $mAccounts, - 'Identities' => $this->GetIdentities($oAccount) - )); - } - - /** - * @return array - * - * @throws \MailSo\Base\Exceptions\Exception - */ - public function DoTemplates() - { - $oAccount = $this->getAccountFromToken(); - - if (!$this->GetCapa(false, false, \RainLoop\Enumerations\Capa::TEMPLATES, $oAccount)) - { - return $this->FalseResponse(__FUNCTION__); - } - - return $this->DefaultResponse(__FUNCTION__, array( - 'Templates' => $this->GetTemplates($oAccount) - )); - } - - /** - * @param string $sHash - * - * @return int - * - * @throws \MailSo\Base\Exceptions\Exception - */ - public function getAccountUnredCountFromHash($sHash) - { - $iResult = 0; - - $oAccount = $this->GetAccountFromCustomToken($sHash, false); - if ($oAccount) - { - try - { - $oMailClient = \MailSo\Mail\MailClient::NewInstance(); - $oMailClient->SetLogger($this->Logger()); - - $oAccount->IncConnectAndLoginHelper($this->Plugins(),$oMailClient, $this->Config()); - - $iResult = $oMailClient->InboxUnreadCount(); - - $oMailClient->LogoutAndDisconnect(); - } - catch (\Exception $oException) - { - $this->Logger()->WriteException($oException); - } - } - - return $iResult; - } - - /** - * @return array - * - * @throws \MailSo\Base\Exceptions\Exception - */ - public function DoAccountsCounts() - { - $oAccount = $this->getAccountFromToken(); - - $bComplete = true; - $aCounts = array(); - - if ($this->GetCapa(false, false, \RainLoop\Enumerations\Capa::ADDITIONAL_ACCOUNTS, $oAccount)) - { - $iLimit = 7; - $mAccounts = $this->GetAccounts($oAccount); - if (\is_array($mAccounts) && 0 < \count($mAccounts)) - { - if ($iLimit > \count($mAccounts)) - { - $mAccounts = \array_slice($mAccounts, 0, $iLimit); - } - else - { - $bComplete = false; - } - - if (0 < \count($mAccounts)) - { - foreach ($mAccounts as $sEmail => $sHash) - { - $aCounts[] = array(\MailSo\Base\Utils::IdnToUtf8($sEmail), - $oAccount->Email() === $sEmail ? 0 : $this->getAccountUnredCountFromHash($sHash)); - } - } - } - } - else - { - $aCounts[] = array(\MailSo\Base\Utils::IdnToUtf8($oAccount->Email()), 0); - } - - return $this->DefaultResponse(__FUNCTION__, array( - 'Complete' => $bComplete, - 'Counts' => $aCounts - )); - } - - /** - * @param \RainLoop\Model\Account $oAccount - */ - public function ClearSignMeData($oAccount) - { - if ($oAccount) - { - \RainLoop\Utils::ClearCookie(\RainLoop\Actions::AUTH_SIGN_ME_TOKEN_KEY); - - $this->StorageProvider()->Clear($oAccount, - \RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG, - 'sign_me' - ); - } - } - - /** - * @return array - */ - public function DoLogout() - { - $oAccount = $this->getAccountFromToken(false); - if ($oAccount) - { - if ($oAccount->SignMe()) - { - $this->ClearSignMeData($oAccount); - } - - if (!$oAccount->IsAdditionalAccount()) - { - \RainLoop\Utils::ClearCookie(\RainLoop\Actions::AUTH_SPEC_TOKEN_KEY); - } - } - - return $this->TrueResponse(__FUNCTION__); - } - - /** - * @return array - */ - public function DoAppDelayStart() - { - $this->Plugins()->RunHook('service.app-delay-start-begin'); - - \RainLoop\Utils::UpdateConnectionToken(); - - $bMainCache = false; - $bFilesCache = false; - $bVersionsCache = false; - - $iOneDay1 = 60 * 60 * 23; - $iOneDay2 = 60 * 60 * 25; - $iOneDay3 = 60 * 60 * 30; - - $sTimers = $this->StorageProvider()->Get(null, - \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, 'Cache/Timers', ''); - - $aTimers = \explode(',', $sTimers); - - $iMainCacheTime = !empty($aTimers[0]) && \is_numeric($aTimers[0]) ? (int) $aTimers[0] : 0; - $iFilesCacheTime = !empty($aTimers[1]) && \is_numeric($aTimers[1]) ? (int) $aTimers[1] : 0; - $iVersionsCacheTime = !empty($aTimers[2]) && \is_numeric($aTimers[2]) ? (int) $aTimers[2] : 0; - - if (0 === $iMainCacheTime || $iMainCacheTime + $iOneDay1 < \time()) - { - $bMainCache = true; - $iMainCacheTime = \time(); - } - - if (0 === $iFilesCacheTime || $iFilesCacheTime + $iOneDay2 < \time()) - { - $bFilesCache = true; - $iFilesCacheTime = \time(); - } - - if (0 === $iVersionsCacheTime || $iVersionsCacheTime + $iOneDay3 < \time()) - { - $bVersionsCache = true; - $iVersionsCacheTime = \time(); - } - - if ($bMainCache || $bFilesCache || $bVersionsCache) - { - if (!$this->StorageProvider()->Put(null, - \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, 'Cache/Timers', - \implode(',', array($iMainCacheTime, $iFilesCacheTime, $iVersionsCacheTime)))) - { - $bMainCache = $bFilesCache = $bVersionsCache = false; - } - } - - if ($bMainCache) - { - $this->Logger()->Write('Cacher GC: Begin'); - $this->Cacher()->GC(48); - $this->Logger()->Write('Cacher GC: End'); - } - else if ($bFilesCache) - { - $this->Logger()->Write('Files GC: Begin'); - $this->FilesProvider()->GC(48); - $this->Logger()->Write('Files GC: End'); - } - else if ($bVersionsCache) - { - $oPremProvider = $this->PremProvider(); - if ($oPremProvider) - { - $oPremProvider->ClearOldVersion(); - } - } - - $this->Plugins()->RunHook('service.app-delay-start-end'); - - return $this->TrueResponse(__FUNCTION__); - } - - /** - * @return array - */ - public function DoSystemFoldersUpdate() - { - $oAccount = $this->getAccountFromToken(); - - $oSettingsLocal = $this->SettingsProvider(true)->Load($oAccount); - - $oSettingsLocal->SetConf('SentFolder', $this->GetActionParam('SentFolder', '')); - $oSettingsLocal->SetConf('DraftFolder', $this->GetActionParam('DraftFolder', '')); - $oSettingsLocal->SetConf('SpamFolder', $this->GetActionParam('SpamFolder', '')); - $oSettingsLocal->SetConf('TrashFolder', $this->GetActionParam('TrashFolder', '')); - $oSettingsLocal->SetConf('ArchiveFolder', $this->GetActionParam('ArchiveFolder', '')); - $oSettingsLocal->SetConf('NullFolder', $this->GetActionParam('NullFolder', '')); - - return $this->DefaultResponse(__FUNCTION__, - $this->SettingsProvider(true)->Save($oAccount, $oSettingsLocal)); - } - - /** - * @param \RainLoop\Config\Application $oConfig - * @param string $sParamName - * @param string $sConfigSector - * @param string $sConfigName - * @param string $sType = 'string' - * @param callable|null $mStringCallback = null - */ - public function setConfigFromParams(&$oConfig, $sParamName, $sConfigSector, $sConfigName, $sType = 'string', $mStringCallback = null) - { - $sValue = $this->GetActionParam($sParamName, ''); - if ($this->HasActionParam($sParamName)) - { - switch ($sType) - { - default: - case 'string': - $sValue = (string) $sValue; - if ($mStringCallback && is_callable($mStringCallback)) - { - $sValue = call_user_func($mStringCallback, $sValue); - } - - $oConfig->Set($sConfigSector, $sConfigName, (string) $sValue); - break; - - case 'dummy': - $sValue = (string) $this->GetActionParam('ContactsPdoPassword', APP_DUMMY); - if (APP_DUMMY !== $sValue) - { - $oConfig->Set($sConfigSector, $sConfigName, (string) $sValue); - } - break; - - case 'int': - $iValue = (int) $sValue; - $oConfig->Set($sConfigSector, $sConfigName, $iValue); - break; - - case 'bool': - $oConfig->Set($sConfigSector, $sConfigName, '1' === (string) $sValue); - break; - } - } - } - - /** - * @param \RainLoop\Config\Application $oConfig - * @param string $sParamName - * @param string $sCapa - */ - private function setCapaFromParams(&$oConfig, $sParamName, $sCapa) - { - switch ($sCapa) - { - case \RainLoop\Enumerations\Capa::ADDITIONAL_ACCOUNTS: - $this->setConfigFromParams($oConfig, $sParamName, 'webmail', 'allow_additional_accounts', 'bool'); - break; - case \RainLoop\Enumerations\Capa::IDENTITIES: - $this->setConfigFromParams($oConfig, $sParamName, 'webmail', 'allow_additional_identities', 'bool'); - break; - case \RainLoop\Enumerations\Capa::TEMPLATES: - $this->setConfigFromParams($oConfig, $sParamName, 'capa', 'x-templates', 'bool'); - break; - case \RainLoop\Enumerations\Capa::TWO_FACTOR: - $this->setConfigFromParams($oConfig, $sParamName, 'security', 'allow_two_factor_auth', 'bool'); - break; - case \RainLoop\Enumerations\Capa::TWO_FACTOR_FORCE: - $this->setConfigFromParams($oConfig, $sParamName, 'security', 'force_two_factor_auth', 'bool'); - break; - case \RainLoop\Enumerations\Capa::GRAVATAR: - $this->setConfigFromParams($oConfig, $sParamName, 'labs', 'allow_gravatar', 'bool'); - break; - case \RainLoop\Enumerations\Capa::ATTACHMENT_THUMBNAILS: - $this->setConfigFromParams($oConfig, $sParamName, 'interface', 'show_attachment_thumbnail', 'bool'); - break; - case \RainLoop\Enumerations\Capa::THEMES: - $this->setConfigFromParams($oConfig, $sParamName, 'webmail', 'allow_themes', 'bool'); - break; - case \RainLoop\Enumerations\Capa::USER_BACKGROUND: - $this->setConfigFromParams($oConfig, $sParamName, 'webmail', 'allow_user_background', 'bool'); - break; - case \RainLoop\Enumerations\Capa::OPEN_PGP: - $this->setConfigFromParams($oConfig, $sParamName, 'security', 'openpgp', 'bool'); - break; - } - } - - /** - * @param \RainLoop\Settings $oSettings - * @param string $sConfigName - * @param string $sType = 'string' - * @param callable|null $mStringCallback = null - */ - private function setSettingsFromParams(&$oSettings, $sConfigName, $sType = 'string', $mStringCallback = null) - { - if ($this->HasActionParam($sConfigName)) - { - $sValue = $this->GetActionParam($sConfigName, ''); - switch ($sType) - { - default: - case 'string': - $sValue = (string) $sValue; - if ($mStringCallback && is_callable($mStringCallback)) - { - $sValue = call_user_func($mStringCallback, $sValue); - } - - $oSettings->SetConf($sConfigName, (string) $sValue); - break; - - case 'int': - $iValue = (int) $sValue; - $oSettings->SetConf($sConfigName, $iValue); - break; - - case 'bool': - $oSettings->SetConf($sConfigName, '1' === (string) $sValue); - break; - } - } - } - - /** - * @return array - */ - public function DoAdminSettingsUpdate() - { -// sleep(3); -// return $this->DefaultResponse(__FUNCTION__, false); - - $this->IsAdminLoggined(); - - $oConfig = $this->Config(); - - $self = $this; - - $this->setConfigFromParams($oConfig, 'Language', 'webmail', 'language', 'string', function ($sLanguage) use ($self) { - return $self->ValidateLanguage($sLanguage, '', false); - }); - - $this->setConfigFromParams($oConfig, 'LanguageAdmin', 'webmail', 'language_admin', 'string', function ($sLanguage) use ($self) { - return $self->ValidateLanguage($sLanguage, '', true); - }); - - $this->setConfigFromParams($oConfig, 'Theme', 'webmail', 'theme', 'string', function ($sTheme) use ($self) { - return $self->ValidateTheme($sTheme); - }); - - $this->setConfigFromParams($oConfig, 'VerifySslCertificate', 'ssl', 'verify_certificate', 'bool'); - $this->setConfigFromParams($oConfig, 'AllowSelfSigned', 'ssl', 'allow_self_signed', 'bool'); - - $this->setConfigFromParams($oConfig, 'UseLocalProxyForExternalImages', 'labs', 'use_local_proxy_for_external_images', 'bool'); - - $this->setConfigFromParams($oConfig, 'NewMoveToFolder', 'interface', 'new_move_to_folder_button', 'bool'); - - $this->setConfigFromParams($oConfig, 'AllowLanguagesOnSettings', 'webmail', 'allow_languages_on_settings', 'bool'); - $this->setConfigFromParams($oConfig, 'AllowLanguagesOnLogin', 'login', 'allow_languages_on_login', 'bool'); - $this->setConfigFromParams($oConfig, 'AttachmentLimit', 'webmail', 'attachment_size_limit', 'int'); - - $this->setConfigFromParams($oConfig, 'LoginDefaultDomain', 'login', 'default_domain', 'string'); - - $this->setConfigFromParams($oConfig, 'ContactsEnable', 'contacts', 'enable', 'bool'); - $this->setConfigFromParams($oConfig, 'ContactsSync', 'contacts', 'allow_sync', 'bool'); - $this->setConfigFromParams($oConfig, 'ContactsPdoDsn', 'contacts', 'pdo_dsn', 'string'); - $this->setConfigFromParams($oConfig, 'ContactsPdoUser', 'contacts', 'pdo_user', 'string'); - $this->setConfigFromParams($oConfig, 'ContactsPdoPassword', 'contacts', 'pdo_password', 'dummy'); - - $this->setConfigFromParams($oConfig, 'ContactsPdoType', 'contacts', 'type', 'string', function ($sType) use ($self) { - return $self->ValidateContactPdoType($sType); - }); - - $this->setCapaFromParams($oConfig, 'CapaAdditionalAccounts', \RainLoop\Enumerations\Capa::ADDITIONAL_ACCOUNTS); - $this->setCapaFromParams($oConfig, 'CapaIdentities', \RainLoop\Enumerations\Capa::IDENTITIES); - $this->setCapaFromParams($oConfig, 'CapaTemplates', \RainLoop\Enumerations\Capa::TEMPLATES); - $this->setCapaFromParams($oConfig, 'CapaTwoFactorAuth', \RainLoop\Enumerations\Capa::TWO_FACTOR); - $this->setCapaFromParams($oConfig, 'CapaTwoFactorAuthForce', \RainLoop\Enumerations\Capa::TWO_FACTOR_FORCE); - $this->setCapaFromParams($oConfig, 'CapaOpenPGP', \RainLoop\Enumerations\Capa::OPEN_PGP); - $this->setCapaFromParams($oConfig, 'CapaGravatar', \RainLoop\Enumerations\Capa::GRAVATAR); - $this->setCapaFromParams($oConfig, 'CapaThemes', \RainLoop\Enumerations\Capa::THEMES); - $this->setCapaFromParams($oConfig, 'CapaUserBackground', \RainLoop\Enumerations\Capa::USER_BACKGROUND); - $this->setCapaFromParams($oConfig, 'CapaAttachmentThumbnails', \RainLoop\Enumerations\Capa::ATTACHMENT_THUMBNAILS); - - $this->setConfigFromParams($oConfig, 'DetermineUserLanguage', 'login', 'determine_user_language', 'bool'); - $this->setConfigFromParams($oConfig, 'DetermineUserDomain', 'login', 'determine_user_domain', 'bool'); - - $this->setConfigFromParams($oConfig, 'Title', 'webmail', 'title', 'string'); - $this->setConfigFromParams($oConfig, 'LoadingDescription', 'webmail', 'loading_description', 'string'); - $this->setConfigFromParams($oConfig, 'FaviconUrl', 'webmail', 'favicon_url', 'string'); - - $this->setConfigFromParams($oConfig, 'TokenProtection', 'security', 'csrf_protection', 'bool'); - $this->setConfigFromParams($oConfig, 'EnabledPlugins', 'plugins', 'enable', 'bool'); - - $this->setConfigFromParams($oConfig, 'GoogleEnable', 'social', 'google_enable', 'bool'); - $this->setConfigFromParams($oConfig, 'GoogleEnableAuth', 'social', 'google_enable_auth', 'bool'); - $this->setConfigFromParams($oConfig, 'GoogleEnableAuthFast', 'social', 'google_enable_auth_fast', 'bool'); - $this->setConfigFromParams($oConfig, 'GoogleEnableDrive', 'social', 'google_enable_drive', 'bool'); - $this->setConfigFromParams($oConfig, 'GoogleEnablePreview', 'social', 'google_enable_preview', 'bool'); - $this->setConfigFromParams($oConfig, 'GoogleClientID', 'social', 'google_client_id', 'string'); - $this->setConfigFromParams($oConfig, 'GoogleClientSecret', 'social', 'google_client_secret', 'string'); - $this->setConfigFromParams($oConfig, 'GoogleApiKey', 'social', 'google_api_key', 'string'); - - $this->setConfigFromParams($oConfig, 'FacebookEnable', 'social', 'fb_enable', 'bool'); - $this->setConfigFromParams($oConfig, 'FacebookAppID', 'social', 'fb_app_id', 'string'); - $this->setConfigFromParams($oConfig, 'FacebookAppSecret', 'social', 'fb_app_secret', 'string'); - - $this->setConfigFromParams($oConfig, 'TwitterEnable', 'social', 'twitter_enable', 'bool'); - $this->setConfigFromParams($oConfig, 'TwitterConsumerKey', 'social', 'twitter_consumer_key', 'string'); - $this->setConfigFromParams($oConfig, 'TwitterConsumerSecret', 'social', 'twitter_consumer_secret', 'string'); - - $this->setConfigFromParams($oConfig, 'DropboxEnable', 'social', 'dropbox_enable', 'bool'); - $this->setConfigFromParams($oConfig, 'DropboxApiKey', 'social', 'dropbox_api_key', 'string'); - - $oPremProvider = $this->PremProvider(); - if ($oPremProvider) - { - $oPremProvider->PremSection($this, $oConfig); - } - - return $this->DefaultResponse(__FUNCTION__, $oConfig->Save()); - } - - /** - * @return array - * - * @throws \MailSo\Base\Exceptions\Exception - */ - public function DoAdminLogin() - { - $sLogin = trim($this->GetActionParam('Login', '')); - $sPassword = $this->GetActionParam('Password', ''); - - $this->Logger()->AddSecret($sPassword); - - if (0 === strlen($sLogin) || 0 === strlen($sPassword) || - !$this->Config()->Get('security', 'allow_admin_panel', true) || - $sLogin !== $this->Config()->Get('security', 'admin_login', '') || - !$this->Config()->ValidatePassword($sPassword)) - { - $this->loginErrorDelay(); - $this->LoggerAuthHelper(null, $this->getAdditionalLogParamsByUserLogin($sLogin, true)); - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::AuthError); - } - - $sToken = $this->getAdminToken(); - $this->setAdminAuthToken($sToken); - - return $this->DefaultResponse(__FUNCTION__, $sToken ? true : false); - } - - /** - * @return array - */ - public function DoAdminLogout() - { - $this->ClearAdminAuthToken(); - return $this->TrueResponse(__FUNCTION__); - } - - /** - * @return array - */ - public function DoAdminPing() - { - $this->IsAdminLoggined(); - - return $this->DefaultResponse(__FUNCTION__, true); - } - - /** - * @return array - */ - public function DoAdminContactsTest() - { - $this->IsAdminLoggined(); - - $oConfig = $this->Config(); - - $this->setConfigFromParams($oConfig, 'ContactsPdoDsn', 'contacts', 'pdo_dsn', 'string'); - $this->setConfigFromParams($oConfig, 'ContactsPdoUser', 'contacts', 'pdo_user', 'string'); - $this->setConfigFromParams($oConfig, 'ContactsPdoPassword', 'contacts', 'pdo_password', 'dummy'); - - $self = $this; - $this->setConfigFromParams($oConfig, 'ContactsPdoType', 'contacts', 'type', 'string', function ($sType) use ($self) { - return $self->ValidateContactPdoType($sType); - }); - - $sTestMessage = $this->AddressBookProvider(null, true)->Test(); - return $this->DefaultResponse(__FUNCTION__, array( - 'Result' => '' === $sTestMessage, - 'Message' => \MailSo\Base\Utils::Utf8Clear($sTestMessage, '?') - )); - } - - /** - * @return array - */ - public function DoAdminLicensing() - { - $this->IsAdminLoggined(); - - $bForce = '1' === (string) $this->GetActionParam('Force', '0'); - - $mResult = false; - $iErrorCode = -1; - - $oPremProvider = $this->PremProvider(); - - if ($oPremProvider && 2 < \strlen(APP_SITE)) - { - $sValue = $oPremProvider->Fetcher($bForce); - - $this->requestSleep(); - - $iExpired = 0; - if ($oPremProvider->Parser($sValue, $iExpired)) - { - $mResult = array( - 'Banned' => false, - 'Expired' => $iExpired, - ); - } - else if ($sValue === 'NO' || \preg_match('/^EXPIRED:[\d]+$/', $sValue)) - { - $iErrorCode = -1; - } - else if ($sValue === 'TOO_MANY_CONNECTIONS') - { - $iErrorCode = -1; - } - else - { - $iErrorCode = \RainLoop\Notifications::LicensingServerIsUnavailable; - } - } - - if (0 < $iErrorCode && !$mResult) - { - throw new \RainLoop\Exceptions\ClientException($iErrorCode); - } - - return $this->DefaultResponse(__FUNCTION__, $mResult); - } - - /** - * @return array - */ - public function DoAdminLicensingActivate() - { - $this->IsAdminLoggined(); - - $sDomain = (string) $this->GetActionParam('Domain', ''); - $sKey = (string) $this->GetActionParam('Key', ''); - - $mResult = false; - $iErrorCode = -1; - - $oPrem = $this->PremProvider(); - - if ($oPrem && 2 < \strlen($sDomain) && 2 < \strlen($sKey) && $sDomain === APP_SITE) - { - $iCode = 0; - $sValue = $oPrem->Activate($sDomain, $sKey, $iCode); - - $this->requestSleep(); - - $aMatch = array(); - if ('OK' === $sValue) - { - $mResult = true; - } - else if ('TOO_MANY_CONNECTIONS' === $sValue) - { - $mResult = 'Too many connections. Please try again later.'; - } - else if (\preg_match('/^ERROR:(.+)$/', $sValue, $aMatch) && !empty($aMatch[1])) - { - $mResult = trim($aMatch[1]); - - $this->Logger()->Write('Activation error for: '.$sKey.' ('.$sDomain.')', \MailSo\Log\Enumerations\Type::ERROR); - $this->Logger()->Write($mResult, \MailSo\Log\Enumerations\Type::ERROR); - } - else - { - $iErrorCode = \RainLoop\Notifications::LicensingServerIsUnavailable; - } - } - - if (0 < $iErrorCode && !$mResult) - { - throw new \RainLoop\Exceptions\ClientException($iErrorCode); - } - - return $this->DefaultResponse(__FUNCTION__, $mResult); - } - - /** - * @return array - */ - public function DoAdminPasswordUpdate() - { - $this->IsAdminLoggined(); - - $bResult = false; - $oConfig = $this->Config(); - - $sLogin = \trim($this->GetActionParam('Login', '')); - $sPassword = $this->GetActionParam('Password', ''); - $this->Logger()->AddSecret($sPassword); - - $sNewPassword = $this->GetActionParam('NewPassword', ''); - if (0 < \strlen(\trim($sNewPassword))) - { - $this->Logger()->AddSecret($sNewPassword); - } - - if ($oConfig->ValidatePassword($sPassword)) - { - if (0 < \strlen($sLogin)) - { - $oConfig->Set('security', 'admin_login', $sLogin); - } - - if (0 < \strlen(\trim($sNewPassword))) - { - $oConfig->SetPassword($sNewPassword); - } - - $bResult = true; - } - - return $this->DefaultResponse(__FUNCTION__, $bResult ? - ($oConfig->Save() ? array('Weak' => $oConfig->ValidatePassword('12345')) : false) : false); - } - - /** - * @return array - */ - public function DoAdminDomainLoad() - { - $this->IsAdminLoggined(); - - return $this->DefaultResponse(__FUNCTION__, - $this->DomainProvider()->Load($this->GetActionParam('Name', ''), false, false)); - } - - /** - * @return array - */ - public function DoAdminDomainList() - { - $this->IsAdminLoggined(); - - $iOffset = (int) $this->GetActionParam('Offset', 0); - $iLimit = (int) $this->GetActionParam('Limit', 20); - $sSearch = (string) $this->GetActionParam('Search', ''); - $bIncludeAliases = '1' === (string) $this->GetActionParam('IncludeAliases', '1'); - - $iOffset = 0; - $sSearch = ''; - $iLimit = $this->Config()->Get('labs', 'domain_list_limit', 99); - - return $this->DefaultResponse(__FUNCTION__, - $this->DomainProvider()->GetList($iOffset, $iLimit, $sSearch, $bIncludeAliases)); - } - - /** - * @return array - */ - public function DoAdminDomainDelete() - { - $this->IsAdminLoggined(); - - return $this->DefaultResponse(__FUNCTION__, - $this->DomainProvider()->Delete((string) $this->GetActionParam('Name', ''))); - } - - /** - * @return array - */ - public function DoAdminDomainDisable() - { - $this->IsAdminLoggined(); - - return $this->DefaultResponse(__FUNCTION__, $this->DomainProvider()->Disable( - (string) $this->GetActionParam('Name', ''), - '1' === (string) $this->GetActionParam('Disabled', '0') - )); - } - - /** - * @return array - */ - public function DoAdminDomainSave() - { - $this->IsAdminLoggined(); - - $oDomain = $this->DomainProvider()->LoadOrCreateNewFromAction($this); - - return $this->DefaultResponse(__FUNCTION__, - $oDomain instanceof \RainLoop\Model\Domain ? $this->DomainProvider()->Save($oDomain) : false); - } - - /** - * @return array - */ - public function DoAdminDomainAliasSave() - { - $this->IsAdminLoggined(); - - return $this->DefaultResponse(__FUNCTION__, $this->DomainProvider()->SaveAlias( - (string) $this->GetActionParam('Name', ''), - (string) $this->GetActionParam('Alias', '') - )); - } - - /** - * @return array - */ - public function DoAdminDomainTest() - { - $this->IsAdminLoggined(); - - $bImapResult = false; - $sImapErrorDesc = ''; - $bSmtpResult = false; - $sSmtpErrorDesc = ''; - $bSieveResult = false; - $sSieveErrorDesc = ''; - - $iImapTime = 0; - $iSmtpTime = 0; - $iSieveTime = 0; - - $iConnectionTimeout = 5; - - $oDomain = $this->DomainProvider()->LoadOrCreateNewFromAction($this, 'domain-test-connection.de'); - if ($oDomain) - { - try - { - $oImapClient = \MailSo\Imap\ImapClient::NewInstance()->SetLogger($this->Logger()); - $oImapClient->SetTimeOuts($iConnectionTimeout); - - $iTime = \microtime(true); - $oImapClient->Connect($oDomain->IncHost(), $oDomain->IncPort(), $oDomain->IncSecure(), - !!$this->Config()->Get('ssl', 'verify_certificate', false), - !!$this->Config()->Get('ssl', 'allow_self_signed', true) - ); - - $iImapTime = \microtime(true) - $iTime; - $oImapClient->Disconnect(); - $bImapResult = true; - } - catch (\MailSo\Net\Exceptions\SocketCanNotConnectToHostException $oException) - { - $this->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); - $sImapErrorDesc = $oException->getSocketMessage(); - if (empty($sImapErrorDesc)) - { - $sImapErrorDesc = $oException->getMessage(); - } - } - catch (\Exception $oException) - { - $this->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); - $sImapErrorDesc = $oException->getMessage(); - } - - if ($oDomain->OutUsePhpMail()) - { - $bSmtpResult = \MailSo\Base\Utils::FunctionExistsAndEnabled('mail'); - if (!$bSmtpResult) - { - $sSmtpErrorDesc = 'PHP: mail() function is undefined'; - } - } - else - { - try - { - $oSmtpClient = \MailSo\Smtp\SmtpClient::NewInstance()->SetLogger($this->Logger()); - $oSmtpClient->SetTimeOuts($iConnectionTimeout); - - $iTime = \microtime(true); - $oSmtpClient->Connect($oDomain->OutHost(), $oDomain->OutPort(), - \MailSo\Smtp\SmtpClient::EhloHelper(), $oDomain->OutSecure(), - !!$this->Config()->Get('ssl', 'verify_certificate', false), - !!$this->Config()->Get('ssl', 'allow_self_signed', true) - ); - - $iSmtpTime = \microtime(true) - $iTime; - $oSmtpClient->Disconnect(); - $bSmtpResult = true; - } - catch (\MailSo\Net\Exceptions\SocketCanNotConnectToHostException $oException) - { - $this->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); - $sSmtpErrorDesc = $oException->getSocketMessage(); - if (empty($sSmtpErrorDesc)) - { - $sSmtpErrorDesc = $oException->getMessage(); - } - } - catch (\Exception $oException) - { - $this->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); - $sSmtpErrorDesc = $oException->getMessage(); - } - } - - if ($oDomain->UseSieve()) - { - try - { - $oSieveClient = \MailSo\Sieve\ManageSieveClient::NewInstance()->SetLogger($this->Logger()); - $oSieveClient->SetTimeOuts($iConnectionTimeout); - $oSieveClient->__USE_INITIAL_AUTH_PLAIN_COMMAND = !!$this->Config()->Get('labs', 'sieve_auth_plain_initial', true); - - $iTime = \microtime(true); - $oSieveClient->Connect($oDomain->SieveHost(), $oDomain->SievePort(), $oDomain->SieveSecure(), - !!$this->Config()->Get('ssl', 'verify_certificate', false), - !!$this->Config()->Get('ssl', 'allow_self_signed', true) - ); - - $iSieveTime = \microtime(true) - $iTime; - $oSieveClient->Disconnect(); - $bSieveResult = true; - } - catch (\MailSo\Net\Exceptions\SocketCanNotConnectToHostException $oException) - { - $this->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); - $sSieveErrorDesc = $oException->getSocketMessage(); - if (empty($sSieveErrorDesc)) - { - $sSieveErrorDesc = $oException->getMessage(); - } - } - catch (\Exception $oException) - { - $this->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); - $sSieveErrorDesc = $oException->getMessage(); - } - } - else - { - $bSieveResult = true; - } - } - - return $this->DefaultResponse(__FUNCTION__, array( - 'Imap' => $bImapResult ? true : $sImapErrorDesc, - 'Smtp' => $bSmtpResult ? true : $sSmtpErrorDesc, - 'Sieve' => $bSieveResult ? true : $sSieveErrorDesc - )); - } - - /** - * @return string - */ - private function rainLoopRepo() - { - $sUrl = APP_REPOSITORY_PATH; - if ('' !== $sUrl) - { - $sUrl = rtrim($sUrl, '\\/').'/'; - } - - return $sUrl; - } - - private function rainLoopUpdatable() - { - return @file_exists(APP_INDEX_ROOT_PATH.'index.php') && - @is_writable(APP_INDEX_ROOT_PATH.'index.php') && - @is_writable(APP_INDEX_ROOT_PATH.'rainloop/') && - APP_VERSION !== APP_DEV_VERSION - ; - } - - private function rainLoopCoreAccess() - { - $sCoreAccess = \strtolower(\preg_replace('/[\s,;]+/', ' ', - $this->Config()->Get('security', 'core_install_access_domain', ''))); - - return '' === $sCoreAccess || '*' === $sCoreAccess || APP_SITE === $sCoreAccess; - } - - /** - * @param string $sRepo - * @param bool $bReal = false - * - * @return array - */ - private function getRepositoryDataByUrl($sRepo, &$bReal = false) - { - $bReal = false; - $aRep = null; - - $sRep = ''; - $sRepoFile = 'repository.json'; - $iRepTime = 0; - - $oHttp = \MailSo\Base\Http::SingletonInstance(); - - $sCacheKey = \RainLoop\KeyPathHelper::RepositoryCacheFile($sRepo, $sRepoFile); - $sRep = $this->Cacher()->Get($sCacheKey); - if ('' !== $sRep) - { - $iRepTime = $this->Cacher()->GetTimer($sCacheKey); - } - - if ('' === $sRep || 0 === $iRepTime || time() - 3600 > $iRepTime) - { - $iCode = 0; - $sContentType = ''; - - $sRepPath = $sRepo.$sRepoFile; - $sRep = '' !== $sRepo ? $oHttp->GetUrlAsString($sRepPath, 'RainLoop', $sContentType, $iCode, $this->Logger(), 10, - $this->Config()->Get('labs', 'curl_proxy', ''), $this->Config()->Get('labs', 'curl_proxy_auth', '')) : false; - - if (false !== $sRep) - { - $aRep = @\json_decode($sRep); - $bReal = \is_array($aRep) && 0 < \count($aRep); - - if ($bReal) - { - $this->Cacher()->Set($sCacheKey, $sRep); - $this->Cacher()->SetTimer($sCacheKey); - } - } - else - { - $this->Logger()->Write('Cannot read remote repository file: '.$sRepPath, \MailSo\Log\Enumerations\Type::ERROR, 'INSTALLER'); - } - } - else if ('' !== $sRep) - { - $aRep = @\json_decode($sRep, false, 10); - $bReal = \is_array($aRep) && 0 < \count($aRep); - } - - $aResult = array(); - if (\is_array($aRep)) - { - foreach ($aRep as $oItem) - { - if ($oItem && isset($oItem->type, $oItem->id, $oItem->name, - $oItem->version, $oItem->release, $oItem->file, $oItem->description)) - { - if (!empty($oItem->required) && APP_DEV_VERSION !== APP_VERSION && version_compare(APP_VERSION, $oItem->required, '<')) - { - continue; - } - - if (!empty($oItem->depricated) && APP_DEV_VERSION !== APP_VERSION && version_compare(APP_VERSION, $oItem->depricated, '>=')) - { - continue; - } - - if ('plugin' === $oItem->type) - { - $aResult[] = array( - 'type' => $oItem->type, - 'id' => $oItem->id, - 'name' => $oItem->name, - 'installed' => '', - 'version' => $oItem->version, - 'file' => $oItem->file, - 'release' => $oItem->release, - 'desc' => $oItem->description - ); - } - } - } - } - - return $aResult; - } - - /** - * @return string - */ - private function getCoreChannel() - { - $sChannel = \trim(\strtolower($this->Config()->Get('labs', 'update_channel', 'stable'))); - if (empty($sChannel) || !\in_array($sChannel, array('stable', 'beta'))) - { - $sChannel = 'stable'; - } - - return $sChannel; - } - - private function getCoreData(&$bReal) - { - $bReal = false; - - $sChannel = $this->getCoreChannel(); - - $sRepo = \str_replace('{{channel}}', $sChannel, APP_REPO_CORE_FILE); - - $oHttp = \MailSo\Base\Http::SingletonInstance(); - - $sCacheKey = \RainLoop\KeyPathHelper::RepositoryCacheCore($sRepo); - $sRep = $this->Cacher()->Get($sCacheKey); - if ('' !== $sRep) - { - $iRepTime = $this->Cacher()->GetTimer($sCacheKey); - } - - if ('' === $sRep || 0 === $iRepTime || time() - 3600 > $iRepTime) - { - $iCode = 0; - $sContentType = ''; - - $sRep = '' !== $sRepo ? $oHttp->GetUrlAsString($sRepo, 'RainLoop', $sContentType, $iCode, $this->Logger(), 10, - $this->Config()->Get('labs', 'curl_proxy', ''), $this->Config()->Get('labs', 'curl_proxy_auth', '')) : false; - - if (false !== $sRep) - { - $aRep = @\json_decode($sRep, true, 10); - $bReal = \is_array($aRep) && 0 < \count($aRep) && isset($aRep['id']) && 'rainloop' === $aRep['id']; - - if ($bReal) - { - $this->Cacher()->Set($sCacheKey, $sRep); - $this->Cacher()->SetTimer($sCacheKey); - } - } - else - { - $this->Logger()->Write('Cannot read remote repository file: '.$sRepo, \MailSo\Log\Enumerations\Type::ERROR, 'INSTALLER'); - } - } - else if ('' !== $sRep) - { - $aRep = @\json_decode($sRep, true, 10); - $bReal = \is_array($aRep) && 0 < \count($aRep) && isset($aRep['id']) && 'rainloop' === $aRep['id']; - } - - return $bReal ? $aRep : false; - } - - private function getRepositoryData(&$bReal, &$bRainLoopUpdatable) - { - $bRainLoopUpdatable = $this->rainLoopUpdatable(); - - $aResult = $this->getRepositoryDataByUrl($this->rainLoopRepo(), $bReal); - - $aSub = array(); - if (\is_array($aResult)) - { - foreach ($aResult as $aItem) - { - if ('plugin' === $aItem['type']) - { - $aSub[] = $aItem; - } - } - - $aResult = $aSub; - unset($aSub); - } - - $aInstalled = $this->Plugins()->InstalledPlugins(); - if (\is_array($aInstalled)) - { - foreach ($aResult as &$aItem) - { - if ('plugin' === $aItem['type']) - { - foreach ($aInstalled as &$aSubItem) - { - if (\is_array($aSubItem) && isset($aSubItem[0]) && $aSubItem[0] === $aItem['id']) - { - $aSubItem[2] = true; - $aItem['installed'] = $aSubItem[1]; - } - } - } - } - - foreach ($aInstalled as $aSubItemSec) - { - if ($aSubItemSec && !isset($aSubItemSec[2])) - { - \array_push($aResult, array( - 'type' => 'plugin', - 'id' => $aSubItemSec[0], - 'name' => $aSubItemSec[0], - 'installed' => $aSubItemSec[1], - 'version' => '', - 'file' => '', - 'release' => '', - 'desc' => '' - )); - } - } - } - - foreach ($aResult as &$aItem) - { - $aItem['compare'] = \version_compare($aItem['installed'], $aItem['version'], '<'); - $aItem['canBeDeleted'] = '' !== $aItem['installed'] && 'plugin' === $aItem['type']; - $aItem['canBeUpdated'] = $aItem['compare']; - $aItem['canBeInstalled'] = true; - } - - return $aResult; - } - - /** - * @return array - */ - public function DoAdminPackagesList() - { - $this->IsAdminLoggined(); - - $bReal = false; - $bRainLoopUpdatable = false; - $aList = $this->getRepositoryData($bReal, $bRainLoopUpdatable); - - return $this->DefaultResponse(__FUNCTION__, array( - 'Real' => $bReal, - 'MainUpdatable' => $bRainLoopUpdatable, - 'List' => $aList - )); - } - - /** - * @return array - */ - public function DoAdminCoreData() - { - $this->IsAdminLoggined(); - - $bReal = false; - $aData = array(); - - $bRainLoopUpdatable = $this->rainLoopUpdatable(); - $bRainLoopAccess = $this->rainLoopCoreAccess(); - - if ($bRainLoopAccess) - { - $aData = $this->getCoreData($bReal); - } - - $sVersion = empty($aData['version']) ? '' : $aData['version']; - $sType = empty($aData['channel']) ? 'stable' : $aData['channel']; - - $sWarnings = empty($aData['warnings']) ? '' : $aData['warnings']; - $aWarnings = $sWarnings ? explode('|', $sWarnings) : array(); - - $sCurrentVersion = APP_VERSION; - - $bShowWarning = false; - if ($sCurrentVersion !== APP_DEV_VERSION) - { - foreach ($aWarnings as $sWarningVersion) - { - $sWarningVersion = \trim($sWarningVersion); - - if (\version_compare($sCurrentVersion, $sWarningVersion, '<') && - \version_compare($sVersion, $sWarningVersion, '>=')) - { - $bShowWarning = true; - break; - } - } - } - - return $this->DefaultResponse(__FUNCTION__, array( - 'Real' => $bReal, - 'Access' => $bRainLoopAccess, - 'Updatable' => $bRainLoopUpdatable, - 'Warning' => $bShowWarning, - 'Channel' => $this->getCoreChannel(), - 'Type' => $sType, - 'Version' => $sCurrentVersion, - 'RemoteVersion' => $sVersion, - 'RemoteRelease' => empty($aData['release']) ? '' : $aData['release'], - 'VersionCompare' => \version_compare($sCurrentVersion, $sVersion) - )); - } - - /** - * @return array - */ - public function DoAdminUpdateCoreData() - { - $this->IsAdminLoggined(); - - $bReal = false; - - $bRainLoopUpdatable = $this->rainLoopUpdatable(); - $bRainLoopAccess = $this->rainLoopCoreAccess(); - $oPremProvider = $this->PremProvider(); - - $aData = array(); - if ($bRainLoopUpdatable && $bRainLoopAccess) - { - $aData = $this->getCoreData($bReal); - } - - $bResult = false; - if ($bReal && $oPremProvider && !empty($aData['file'])) - { - $bResult = $oPremProvider->UpdateCore($this, $aData['file']); - } - - return $this->DefaultResponse(__FUNCTION__, $bResult); - } - - /** - * @return array - */ - public function DoAdminPackageDelete() - { - $this->IsAdminLoggined(); - - $sId = $this->GetActionParam('Id', ''); - - $bReal = false; - $bRainLoopUpdatable = false; - $aList = $this->getRepositoryData($bReal, $bRainLoopUpdatable); - - $sResultId = ''; - foreach ($aList as $oItem) - { - if ($oItem && 'plugin' === $oItem['type'] && $sId === $oItem['id']) - { - $sResultId = $sId; - break; - } - } - - $bResult = false; - if ('' !== $sResultId) - { - $bResult = \MailSo\Base\Utils::RecRmDir(APP_PLUGINS_PATH.$sResultId); - if ($bResult) - { - $this->pluginEnable($sResultId, false); - } - } - - return $this->DefaultResponse(__FUNCTION__, $bResult); - } - - /** - * @param string $sUrl - * - * @return string - */ - public function downloadRemotePackageByUrl($sUrl) - { - $bResult = false; - $sTmp = APP_PRIVATE_DATA.\md5(\microtime(true).$sUrl).'.zip'; - $pDest = @\fopen($sTmp, 'w+b'); - if ($pDest) - { - $iCode = 0; - $sContentType = ''; - - @\set_time_limit(120); - - $oHttp = \MailSo\Base\Http::SingletonInstance(); - $bResult = $oHttp->SaveUrlToFile($sUrl, $pDest, $sTmp, $sContentType, $iCode, $this->Logger(), 60, - $this->Config()->Get('labs', 'curl_proxy', ''), $this->Config()->Get('labs', 'curl_proxy_auth', '')); - - if (!$bResult) - { - $this->Logger()->Write('Cannot save url to temp file: ', \MailSo\Log\Enumerations\Type::ERROR, 'INSTALLER'); - $this->Logger()->Write($sUrl.' -> '.$sTmp, \MailSo\Log\Enumerations\Type::ERROR, 'INSTALLER'); - } - - @\fclose($pDest); - } - else - { - $this->Logger()->Write('Cannot create temp file: '.$sTmp, \MailSo\Log\Enumerations\Type::ERROR, 'INSTALLER'); - } - - return $bResult ? $sTmp : ''; - } - - /** - * @return array - */ - public function DoAdminPackageInstall() - { - $this->IsAdminLoggined(); - - $sType = $this->GetActionParam('Type', ''); - $sId = $this->GetActionParam('Id', ''); - $sFile = $this->GetActionParam('File', ''); - - $this->Logger()->Write('Start package install: '.$sFile.' ('.$sType.')', \MailSo\Log\Enumerations\Type::INFO, 'INSTALLER'); - - $sRealFile = ''; - - $bReal = false; - $bRainLoopUpdatable = false; - $aList = $this->getRepositoryData($bReal, $bRainLoopUpdatable); - - if ('plugin' === $sType) - { - foreach ($aList as $oItem) - { - if ($oItem && $sFile === $oItem['file'] && $sId === $oItem['id']) - { - $sRealFile = $sFile; - break; - } - } - } - - $sTmp = ''; - $bResult = false; - if ('' !== $sRealFile) - { - $sUrl = $this->rainLoopRepo().$sRealFile; - $sTmp = $this->downloadRemotePackageByUrl($sUrl); - } - - if ('' !== $sTmp) - { - include_once APP_VERSION_ROOT_PATH.'app/libraries/pclzip/pclzip.lib.php'; - - $oArchive = new \PclZip($sTmp); - if ('plugin' === $sType) - { - $bResult = true; - if (\is_dir(APP_PLUGINS_PATH.$sId)) - { - $bResult = \MailSo\Base\Utils::RecRmDir(APP_PLUGINS_PATH.$sId); - if (!$bResult) - { - $this->Logger()->Write('Cannot remove previous plugin folder: '.$sId, \MailSo\Log\Enumerations\Type::ERROR, 'INSTALLER'); - } - } - - if ($bResult) - { - $bResult = 0 !== $oArchive->extract(PCLZIP_OPT_PATH, APP_PLUGINS_PATH); - if (!$bResult) - { - $this->Logger()->Write('Cannot extract package files: '.$oArchive->errorInfo(), \MailSo\Log\Enumerations\Type::ERROR, 'INSTALLER'); - } - } - } - - @\unlink($sTmp); - } - - return $this->DefaultResponse(__FUNCTION__, $bResult ? - ('plugin' !== $sType ? array('Reload' => true) : true) : false); - } - - /** - * @return array - */ - public function DoAdminPluginList() - { - $this->IsAdminLoggined(); - - $aResult = array(); - - $sEnabledPlugins = $this->Config()->Get('plugins', 'enabled_list', ''); - $aEnabledPlugins = \explode(',', \strtolower($sEnabledPlugins)); - $aEnabledPlugins = \array_map('trim', $aEnabledPlugins); - - $aList = $this->Plugins()->InstalledPlugins(); - foreach ($aList as $aItem) - { - $aResult[] = array( - 'Name' => $aItem[0], - 'Enabled' => \in_array(\strtolower($aItem[0]), $aEnabledPlugins), - 'Configured' => false - ); - } - - return $this->DefaultResponse(__FUNCTION__, $aResult); - } - - /** - * @param string $sName - * @param bool $bEnable = true - * @return bool - */ - private function pluginEnable($sName, $bEnable = true) - { - if (0 === \strlen($sName)) - { - return false; - } - - $oConfig = $this->Config(); - - $sEnabledPlugins = $oConfig->Get('plugins', 'enabled_list', ''); - $aEnabledPlugins = \explode(',', \strtolower($sEnabledPlugins)); - $aEnabledPlugins = \array_map('trim', $aEnabledPlugins); - - $aNewEnabledPlugins = array(); - if ($bEnable) - { - $aNewEnabledPlugins = $aEnabledPlugins; - $aNewEnabledPlugins[] = $sName; - } - else - { - foreach ($aEnabledPlugins as $sPlugin) - { - if ($sName !== $sPlugin && 0 < \strlen($sPlugin)) - { - $aNewEnabledPlugins[] = $sPlugin; - } - } - } - - $aNewEnabledPlugins = \array_unique($aNewEnabledPlugins); - $oConfig->Set('plugins', 'enabled_list', \trim(\implode(',', $aNewEnabledPlugins), ' ,')); - - return $oConfig->Save(); - } - - /** - * @return array - */ - public function DoAdminPluginDisable() - { - $this->IsAdminLoggined(); - - $sName = (string) $this->GetActionParam('Name', ''); - $bDisable = '1' === (string) $this->GetActionParam('Disabled', '1'); - - if (!$bDisable) - { - $oPlugin = $this->Plugins()->CreatePluginByName($sName); - if ($oPlugin && ($oPlugin instanceof \RainLoop\Plugins\AbstractPlugin)) - { - $sValue = $oPlugin->Supported(); - if (0 < \strlen($sValue)) - { - return $this->FalseResponse(__FUNCTION__, \RainLoop\Notifications::UnsupportedPluginPackage, $sValue); - } - } - else - { - return $this->FalseResponse(__FUNCTION__, \RainLoop\Notifications::InvalidPluginPackage); - } - } - - return $this->DefaultResponse(__FUNCTION__, $this->pluginEnable($sName, !$bDisable)); - } - - /** - * @return array - */ - public function DoAdminPluginLoad() - { - $this->IsAdminLoggined(); - - $mResult = false; - $sName = (string) $this->GetActionParam('Name', ''); - - if (!empty($sName)) - { - $oPlugin = $this->Plugins()->CreatePluginByName($sName); - if ($oPlugin) - { - $mResult = array( - 'Name' => $sName, - 'Readme' => file_exists($oPlugin->Path().'/README') ? file_get_contents($oPlugin->Path().'/README') : '', - 'Config' => array() - ); - - $aMap = $oPlugin->ConfigMap(); - $oConfig = $oPlugin->Config(); - if (is_array($aMap) && 0 < count($aMap)) - { - foreach ($aMap as $oItem) - { - if ($oItem && ($oItem instanceof \RainLoop\Plugins\Property)) - { - $aItem = $oItem->ToArray(); - $aItem[0] = $oConfig->Get('plugin', $oItem->Name(), ''); - if (\RainLoop\Enumerations\PluginPropertyType::PASSWORD === $oItem->Type()) - { - $aItem[0] = APP_DUMMY; - } - - $mResult['Config'][] = $aItem; - } - } - } - } - } - - return $this->DefaultResponse(__FUNCTION__, $mResult); - } - - /** - * @return array - */ - public function DoAdminPluginSettingsUpdate() - { - $this->IsAdminLoggined(); - - $mResult = false; - $sName = (string) $this->GetActionParam('Name', ''); - - if (!empty($sName)) - { - $oPlugin = $this->Plugins()->CreatePluginByName($sName); - if ($oPlugin) - { - $oConfig = $oPlugin->Config(); - $aMap = $oPlugin->ConfigMap(); - if (is_array($aMap) && 0 < count($aMap)) - { - foreach ($aMap as $oItem) - { - $sValue = $this->GetActionParam('_'.$oItem->Name(), $oConfig->Get('plugin', $oItem->Name())); - if (\RainLoop\Enumerations\PluginPropertyType::PASSWORD !== $oItem->Type() || APP_DUMMY !== $sValue) - { - $mResultValue = null; - switch ($oItem->Type()) { - case \RainLoop\Enumerations\PluginPropertyType::INT: - $mResultValue = (int) $sValue; - break; - case \RainLoop\Enumerations\PluginPropertyType::BOOL: - $mResultValue = '1' === (string) $sValue; - break; - case \RainLoop\Enumerations\PluginPropertyType::SELECTION: - if (is_array($oItem->DefaultValue()) && in_array($sValue, $oItem->DefaultValue())) - { - $mResultValue = (string) $sValue; - } - break; - case \RainLoop\Enumerations\PluginPropertyType::PASSWORD: - case \RainLoop\Enumerations\PluginPropertyType::STRING: - case \RainLoop\Enumerations\PluginPropertyType::STRING_TEXT: - $mResultValue = (string) $sValue; - break; - } - - if (null !== $mResultValue) - { - $oConfig->Set('plugin', $oItem->Name(), $mResultValue); - } - } - } - } - - $mResult = $oConfig->Save(); - } - } - - if (!$mResult) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CantSavePluginSettings); - } - - return $this->DefaultResponse(__FUNCTION__, true); - } - - /** - * @return array - */ - public function DoSettingsUpdate() - { - $oAccount = $this->getAccountFromToken(); - if (!$this->GetCapa(false, false, \RainLoop\Enumerations\Capa::SETTINGS, $oAccount)) - { - return $this->FalseResponse(__FUNCTION__); - } - - $self = $this; - $oConfig = $this->Config(); - - $oSettings = $this->SettingsProvider()->Load($oAccount); - $oSettingsLocal = $this->SettingsProvider(true)->Load($oAccount); - - if ($oConfig->Get('webmail', 'allow_languages_on_settings', true)) - { - $this->setSettingsFromParams($oSettings, 'Language', 'string', function ($sLanguage) use ($self) { - return $self->ValidateLanguage($sLanguage); - }); - } - else - { - $oSettings->SetConf('Language', $this->ValidateLanguage($oConfig->Get('webmail', 'language', 'en'))); - } - - if ($this->GetCapa(false, false, \RainLoop\Enumerations\Capa::THEMES, $oAccount)) - { - $this->setSettingsFromParams($oSettingsLocal, 'Theme', 'string', function ($sTheme) use ($self) { - return $self->ValidateTheme($sTheme); - }); - } - else - { - $oSettingsLocal->SetConf('Theme', $this->ValidateTheme($oConfig->Get('webmail', 'theme', 'Default'))); - } - - $this->setSettingsFromParams($oSettings, 'MPP', 'int', function ($iValue) { - return (int) (\in_array($iValue, array(10, 20, 30, 50, 100, 150, 200, 300)) ? $iValue : 20); - }); - - $this->setSettingsFromParams($oSettings, 'Layout', 'int', function ($iValue) { - return (int) (\in_array((int) $iValue, array(\RainLoop\Enumerations\Layout::NO_PREVIW, - \RainLoop\Enumerations\Layout::SIDE_PREVIEW, \RainLoop\Enumerations\Layout::BOTTOM_PREVIEW)) ? - $iValue : \RainLoop\Enumerations\Layout::SIDE_PREVIEW); - }); - - $this->setSettingsFromParams($oSettings, 'EditorDefaultType', 'string'); - $this->setSettingsFromParams($oSettings, 'ShowImages', 'bool'); - $this->setSettingsFromParams($oSettings, 'ContactsAutosave', 'bool'); - $this->setSettingsFromParams($oSettings, 'DesktopNotifications', 'bool'); - $this->setSettingsFromParams($oSettings, 'SoundNotification', 'bool'); - $this->setSettingsFromParams($oSettings, 'UseCheckboxesInList', 'bool'); - $this->setSettingsFromParams($oSettings, 'AllowDraftAutosave', 'bool'); - $this->setSettingsFromParams($oSettings, 'AutoLogout', 'int'); - - $this->setSettingsFromParams($oSettings, 'EnableTwoFactor', 'bool'); - - $this->setSettingsFromParams($oSettingsLocal, 'UseThreads', 'bool'); - $this->setSettingsFromParams($oSettingsLocal, 'ReplySameFolder', 'bool'); - - return $this->DefaultResponse(__FUNCTION__, - $this->SettingsProvider()->Save($oAccount, $oSettings) && - $this->SettingsProvider(true)->Save($oAccount, $oSettingsLocal)); - } - - /** - * @return array - */ - public function DoNoop() - { - $this->initMailClientConnection(); - return $this->TrueResponse(__FUNCTION__); - } - - /** - * @return array - */ - public function DoPing() - { - return $this->DefaultResponse(__FUNCTION__, 'Pong'); - } - - /** - * @return array - */ - public function DoChangePassword() - { - $mResult = false; - - $oAccount = $this->getAccountFromToken(); - if ($oAccount) - { - try - { - $mResult = $this->ChangePasswordProvider()->ChangePassword( - $oAccount, - $this->GetActionParam('PrevPassword', ''), - $this->GetActionParam('NewPassword', '') - ); - } - catch (\Exception $oException) - { - $this->loginErrorDelay(); - $this->Logger()->Write('Error: Can\'t change password for '.$oAccount->Email().' account.', \MailSo\Log\Enumerations\Type::NOTICE); - - throw $oException; - } - } - - return $this->DefaultResponse(__FUNCTION__, $mResult); - } - - /** - * @return array - */ - public function DoJsInfo() - { - $bIsError = '1' === (string) $this->GetActionParam('IsError', '0'); - $mData = $this->GetActionParam('Data', null); - - $this->Logger()->WriteDump(is_array($mData) ? $mData : array(), - $bIsError ? \MailSo\Log\Enumerations\Type::ERROR : \MailSo\Log\Enumerations\Type::INFO, 'JS-INFO'); - - return $this->DefaultResponse(__FUNCTION__, true); - } - - /** - * @return array - */ - public function DoWelcomeClose() - { - $oAccount = $this->getAccountFromToken(); - if ($oAccount && !$oAccount->IsAdditionalAccount()) - { - $oSettings = $this->SettingsProvider()->Load($oAccount); - $oSettings->SetConf('LastWelcomePage', - $this->Config()->Get('branding', 'welcome_page_url', '')); - - return $this->DefaultResponse(__FUNCTION__, - $this->SettingsProvider()->Save($oAccount, $oSettings)); - } - - return $this->FalseResponse(__FUNCTION__); - } - - /** - * @return array - */ - public function DoVersion() - { - return $this->DefaultResponse(__FUNCTION__, - APP_VERSION === (string) $this->GetActionParam('Version', '')); - } - - /** - * @return array - */ - public function DoJsError() - { - $sMessage = $this->GetActionParam('Message', ''); - if (0 < strlen($sMessage)) - { - $sFileName = $this->GetActionParam('FileName', ''); - $sLineNo = $this->GetActionParam('LineNo', ''); - $sLocation = $this->GetActionParam('Location', ''); - $sHtmlCapa = $this->GetActionParam('HtmlCapa', ''); - $sTimeOnPage = $this->GetActionParam('TimeOnPage', ''); - - $oHttp = $this->Http(); - - $this->Logger()->Write($sMessage.' ('.$sFileName.' ~ '.$sLineNo.')', \MailSo\Log\Enumerations\Type::ERROR, 'JS'); - $this->Logger()->WriteDump(array( - 'Location' => $sLocation, - 'Capability' => $sHtmlCapa, - 'TimeOnPage' => $sTimeOnPage, - 'HTTP_USER_AGENT' => $oHttp->GetServer('HTTP_USER_AGENT', ''), - 'HTTP_ACCEPT_ENCODING' => $oHttp->GetServer('HTTP_ACCEPT_ENCODING', ''), - 'HTTP_ACCEPT_LANGUAGE' => $oHttp->GetServer('HTTP_ACCEPT_LANGUAGE', '') - )); - } - - return $this->DefaultResponse(__FUNCTION__, true); - } - - /** - * @param \MailSo\Mail\FolderCollection $oFolders - * @return array - */ - private function recFoldersNames($oFolders) - { - $aResult = array(); - if ($oFolders) - { - $aFolders =& $oFolders->GetAsArray(); - - foreach ($aFolders as $oFolder) - { - $aResult[] = $oFolder->FullNameRaw()."|". - implode("|", $oFolder->Flags()).($oFolder->IsSubscribed() ? '1' : '0'); - - $oSub = $oFolder->SubFolders(); - if ($oSub && 0 < $oSub->Count()) - { - $aResult = \array_merge($aResult, $this->recFoldersNames($oSub)); - } - } - } - - return $aResult; - } - - /** - * @staticvar array $aCache - * @param \RainLoop\Model\Account $oAccount - * - * @return array - */ - private function systemFoldersNames($oAccount) - { - static $aCache = null; - if (null === $aCache) - { - $aCache = array( - - 'Sent' => \MailSo\Imap\Enumerations\FolderType::SENT, - 'Send' => \MailSo\Imap\Enumerations\FolderType::SENT, - - 'Outbox' => \MailSo\Imap\Enumerations\FolderType::SENT, - 'Out box' => \MailSo\Imap\Enumerations\FolderType::SENT, - - 'Sent Item' => \MailSo\Imap\Enumerations\FolderType::SENT, - 'Sent Items' => \MailSo\Imap\Enumerations\FolderType::SENT, - 'Send Item' => \MailSo\Imap\Enumerations\FolderType::SENT, - 'Send Items' => \MailSo\Imap\Enumerations\FolderType::SENT, - 'Sent Mail' => \MailSo\Imap\Enumerations\FolderType::SENT, - 'Sent Mails' => \MailSo\Imap\Enumerations\FolderType::SENT, - 'Send Mail' => \MailSo\Imap\Enumerations\FolderType::SENT, - 'Send Mails' => \MailSo\Imap\Enumerations\FolderType::SENT, - - 'Drafts' => \MailSo\Imap\Enumerations\FolderType::DRAFTS, - - 'Draft' => \MailSo\Imap\Enumerations\FolderType::DRAFTS, - 'Draft Mail' => \MailSo\Imap\Enumerations\FolderType::DRAFTS, - 'Draft Mails' => \MailSo\Imap\Enumerations\FolderType::DRAFTS, - 'Drafts Mail' => \MailSo\Imap\Enumerations\FolderType::DRAFTS, - 'Drafts Mails' => \MailSo\Imap\Enumerations\FolderType::DRAFTS, - - 'Junk E-mail' => \MailSo\Imap\Enumerations\FolderType::JUNK, - - 'Spam' => \MailSo\Imap\Enumerations\FolderType::JUNK, - 'Spams' => \MailSo\Imap\Enumerations\FolderType::JUNK, - - 'Junk' => \MailSo\Imap\Enumerations\FolderType::JUNK, - 'Bulk Mail' => \MailSo\Imap\Enumerations\FolderType::JUNK, - 'Bulk Mails' => \MailSo\Imap\Enumerations\FolderType::JUNK, - - 'Deleted Items' => \MailSo\Imap\Enumerations\FolderType::TRASH, - - 'Trash' => \MailSo\Imap\Enumerations\FolderType::TRASH, - 'Deleted' => \MailSo\Imap\Enumerations\FolderType::TRASH, - 'Bin' => \MailSo\Imap\Enumerations\FolderType::TRASH, - - 'Archive' => \MailSo\Imap\Enumerations\FolderType::ALL, - 'Archives' => \MailSo\Imap\Enumerations\FolderType::ALL, - - 'All' => \MailSo\Imap\Enumerations\FolderType::ALL, - 'All Mail' => \MailSo\Imap\Enumerations\FolderType::ALL, - 'All Mails' => \MailSo\Imap\Enumerations\FolderType::ALL, - ); - - $aNewCache = array(); - foreach ($aCache as $sKey => $iType) - { - $aNewCache[$sKey] = $iType; - $aNewCache[\str_replace(' ', '', $sKey)] = $iType; - } - - $aCache = $aNewCache; - - $this->Plugins()->RunHook('filter.system-folders-names', array($oAccount, &$aCache)); - } - - return $aCache; - } - - /** - * @param \RainLoop\Model\Account $oAccount - * @param \MailSo\Mail\FolderCollection $oFolders - * @param array $aResult - * @param bool $bListFolderTypes = true - */ - private function recFoldersTypes($oAccount, $oFolders, &$aResult, $bListFolderTypes = true) - { - if ($oFolders) - { - $aFolders =& $oFolders->GetAsArray(); - if (\is_array($aFolders) && 0 < \count($aFolders)) - { - if ($bListFolderTypes) - { - foreach ($aFolders as $oFolder) - { - $iFolderListType = $oFolder->GetFolderListType(); - if (!isset($aResult[$iFolderListType]) && \in_array($iFolderListType, array( - \MailSo\Imap\Enumerations\FolderType::SENT, - \MailSo\Imap\Enumerations\FolderType::DRAFTS, - \MailSo\Imap\Enumerations\FolderType::JUNK, - \MailSo\Imap\Enumerations\FolderType::TRASH, - \MailSo\Imap\Enumerations\FolderType::ALL - ))) - { - $aResult[$iFolderListType] = $oFolder->FullNameRaw(); - } - } - - foreach ($aFolders as $oFolder) - { - $oSub = $oFolder->SubFolders(); - if ($oSub && 0 < $oSub->Count()) - { - $this->recFoldersTypes($oAccount, $oSub, $aResult, true); - } - } - } - - $aMap = $this->systemFoldersNames($oAccount); - foreach ($aFolders as $oFolder) - { - $sName = $oFolder->Name(); - $sFullName = $oFolder->FullName(); - - if (isset($aMap[$sName]) || isset($aMap[$sFullName])) - { - $iFolderType = isset($aMap[$sName]) ? $aMap[$sName] : $aMap[$sFullName]; - if (!isset($aResult[$iFolderType]) && \in_array($iFolderType, array( - \MailSo\Imap\Enumerations\FolderType::SENT, - \MailSo\Imap\Enumerations\FolderType::DRAFTS, - \MailSo\Imap\Enumerations\FolderType::JUNK, - \MailSo\Imap\Enumerations\FolderType::TRASH, - \MailSo\Imap\Enumerations\FolderType::ALL - ))) - { - $aResult[$iFolderType] = $oFolder->FullNameRaw(); - } - } - } - - foreach ($aFolders as $oFolder) - { - $oSub = $oFolder->SubFolders(); - if ($oSub && 0 < $oSub->Count()) - { - $this->recFoldersTypes($oAccount, $oSub, $aResult, false); - } - } - } - } - } - - /** - * @return array - */ - public function DoFolders() - { - $oAccount = $this->initMailClientConnection(); - - $oFolderCollection = null; - $this->Plugins()->RunHook('filter.folders-before', array($oAccount, &$oFolderCollection)); - - $bUseFolders = $this->GetCapa(false, false, \RainLoop\Enumerations\Capa::FOLDERS, $oAccount); - - if (null === $oFolderCollection) - { - $oFolderCollection = $this->MailClient()->Folders('', - $bUseFolders ? '*' : 'INBOX', - !!$this->Config()->Get('labs', 'use_imap_list_subscribe', true), - (int) $this->Config()->Get('labs', 'imap_folder_list_limit', 200) - ); - } - - $this->Plugins()->RunHook('filter.folders-post', array($oAccount, &$oFolderCollection)); - - if ($oFolderCollection instanceof \MailSo\Mail\FolderCollection) - { - $oSettingsLocal = $this->SettingsProvider(true)->Load($oAccount); - - $aSystemFolders = array(); - $this->recFoldersTypes($oAccount, $oFolderCollection, $aSystemFolders); - $oFolderCollection->SystemFolders = $aSystemFolders; - - if ($bUseFolders && $this->Config()->Get('labs', 'autocreate_system_folders', true)) - { - $bDoItAgain = false; - - $sNamespace = $oFolderCollection->GetNamespace(); - $sParent = empty($sNamespace) ? '' : \substr($sNamespace, 0, -1); - - $sDelimiter = $oFolderCollection->FindDelimiter(); - - $aList = array(); - $aMap = $this->systemFoldersNames($oAccount); - - if ('' === $oSettingsLocal->GetConf('SentFolder', '')) - { - $aList[] = \MailSo\Imap\Enumerations\FolderType::SENT; - } - - if ('' === $oSettingsLocal->GetConf('DraftFolder', '')) - { - $aList[] = \MailSo\Imap\Enumerations\FolderType::DRAFTS; - } - - if ('' === $oSettingsLocal->GetConf('SpamFolder', '')) - { - $aList[] = \MailSo\Imap\Enumerations\FolderType::JUNK; - } - - if ('' === $oSettingsLocal->GetConf('TrashFolder', '')) - { - $aList[] = \MailSo\Imap\Enumerations\FolderType::TRASH; - } - - if ('' === $oSettingsLocal->GetConf('ArchiveFolder', '')) - { - $aList[] = \MailSo\Imap\Enumerations\FolderType::ALL; - } - - $this->Plugins()->RunHook('filter.folders-system-types', array($oAccount, &$aList)); - - foreach ($aList as $iType) - { - if (!isset($aSystemFolders[$iType])) - { - $mFolderNameToCreate = \array_search($iType, $aMap); - if (!empty($mFolderNameToCreate)) - { - $iPos = \strrpos($mFolderNameToCreate, $sDelimiter); - if (false !== $iPos) - { - $mNewParent = \substr($mFolderNameToCreate, 0, $iPos); - $mNewFolderNameToCreate = \substr($mFolderNameToCreate, $iPos + 1); - if (0 < \strlen($mNewFolderNameToCreate)) - { - $mFolderNameToCreate = $mNewFolderNameToCreate; - } - - if (0 < \strlen($mNewParent)) - { - $sParent = 0 < \strlen($sParent) ? $sParent.$sDelimiter.$mNewParent : $mNewParent; - } - } - - $sFullNameToCheck = \MailSo\Base\Utils::ConvertEncoding($mFolderNameToCreate, - \MailSo\Base\Enumerations\Charset::UTF_8, \MailSo\Base\Enumerations\Charset::UTF_7_IMAP); - - if (0 < \strlen(\trim($sParent))) - { - $sFullNameToCheck = $sParent.$sDelimiter.$sFullNameToCheck; - } - - if (!$oFolderCollection->GetByFullNameRaw($sFullNameToCheck)) - { - try - { - if ($this->MailClient()->FolderCreate($mFolderNameToCreate, $sParent, true, $sDelimiter)) - { - $bDoItAgain = true; - } - } - catch (\Exception $oException) - { - $this->Logger()->WriteException($oException); - } - } - } - } - } - - if ($bDoItAgain) - { - $oFolderCollection = $this->MailClient()->Folders('', '*', - !!$this->Config()->Get('labs', 'use_imap_list_subscribe', true), - (int) $this->Config()->Get('labs', 'imap_folder_list_limit', 200) - ); - - if ($oFolderCollection) - { - $aSystemFolders = array(); - $this->recFoldersTypes($oAccount, $oFolderCollection, $aSystemFolders); - $oFolderCollection->SystemFolders = $aSystemFolders; - } - } - } - - if ($oFolderCollection) - { - $oFolderCollection->FoldersHash = \md5(\implode("\x0", $this->recFoldersNames($oFolderCollection))); - } - } - - $this->Plugins()->RunHook('filter.folders-complete', array($oAccount, &$oFolderCollection)); - - return $this->DefaultResponse(__FUNCTION__, $oFolderCollection); - } - - /** - * @return array - */ - public function DoFolderCreate() - { - $oAccount = $this->initMailClientConnection(); - - if (!$this->GetCapa(false, false, \RainLoop\Enumerations\Capa::FOLDERS, $oAccount)) - { - return $this->FalseResponse(__FUNCTION__); - } - - try - { - $sFolderNameInUtf = $this->GetActionParam('Folder', ''); - $sFolderParentFullNameRaw = $this->GetActionParam('Parent', ''); - - $this->MailClient()->FolderCreate($sFolderNameInUtf, $sFolderParentFullNameRaw, - !!$this->Config()->Get('labs', 'use_imap_list_subscribe', true)); - } - catch (\Exception $oException) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CantCreateFolder, $oException); - } - - return $this->TrueResponse(__FUNCTION__); - } - - /** - * @return array - */ - public function DoFolderSubscribe() - { - $oAccount = $this->initMailClientConnection(); - - if (!$this->GetCapa(false, false, \RainLoop\Enumerations\Capa::FOLDERS, $oAccount)) - { - return $this->FalseResponse(__FUNCTION__); - } - - $sFolderFullNameRaw = $this->GetActionParam('Folder', ''); - $bSubscribe = '1' === (string) $this->GetActionParam('Subscribe', '0'); - - try - { - $this->MailClient()->FolderSubscribe($sFolderFullNameRaw, !!$bSubscribe); - } - catch (\Exception $oException) - { - if ($bSubscribe) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CantSubscribeFolder, $oException); - } - else - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CantUnsubscribeFolder, $oException); - } - } - - return $this->TrueResponse(__FUNCTION__); - } - - /** - * @return array - */ - public function DoFolderCheckable() - { - $oAccount = $this->getAccountFromToken(); - - if (!$this->GetCapa(false, false, \RainLoop\Enumerations\Capa::FOLDERS, $oAccount)) - { - return $this->FalseResponse(__FUNCTION__); - } - - $sFolderFullNameRaw = $this->GetActionParam('Folder', ''); - $bCheckable = '1' === (string) $this->GetActionParam('Checkable', '0'); - - $oSettingsLocal = $this->SettingsProvider(true)->Load($oAccount); - - $sCheckableFolder = $oSettingsLocal->GetConf('CheckableFolder', '[]'); - $aCheckableFolder = @\json_decode($sCheckableFolder); - - if (!\is_array($aCheckableFolder)) - { - $aCheckableFolder = array(); - } - - if ($bCheckable) - { - $aCheckableFolder[] = $sFolderFullNameRaw; - } - else - { - $aCheckableFolderNew = array(); - foreach ($aCheckableFolder as $sFolder) - { - if ($sFolder !== $sFolderFullNameRaw) - { - $aCheckableFolderNew[] = $sFolder; - } - } - $aCheckableFolder = $aCheckableFolderNew; - } - - $aCheckableFolder = \array_unique($aCheckableFolder); - - $oSettingsLocal->SetConf('CheckableFolder', @\json_encode($aCheckableFolder)); - - return $this->DefaultResponse(__FUNCTION__, - $this->SettingsProvider(true)->Save($oAccount, $oSettingsLocal)); - } - - /** - * @return array - * - * @throws \MailSo\Base\Exceptions\Exception - */ - public function DoFolderRename() - { - $oAccount = $this->initMailClientConnection(); - - if (!$this->GetCapa(false, false, \RainLoop\Enumerations\Capa::FOLDERS, $oAccount)) - { - return $this->FalseResponse(__FUNCTION__); - } - - $sPrevFolderFullNameRaw = $this->GetActionParam('Folder', ''); - $sNewTopFolderNameInUtf = $this->GetActionParam('NewFolderName', ''); - - try - { - $this->MailClient()->FolderRename($sPrevFolderFullNameRaw, $sNewTopFolderNameInUtf, - !!$this->Config()->Get('labs', 'use_imap_list_subscribe', true)); - } - catch (\Exception $oException) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CantRenameFolder, $oException); - } - - return $this->TrueResponse(__FUNCTION__); - } - - /** - * @return array - * - * @throws \MailSo\Base\Exceptions\Exception - */ - public function DoFolderDelete() - { - $oAccount = $this->initMailClientConnection(); - - if (!$this->GetCapa(false, false, \RainLoop\Enumerations\Capa::FOLDERS, $oAccount)) - { - return $this->FalseResponse(__FUNCTION__); - } - - $sFolderFullNameRaw = $this->GetActionParam('Folder', ''); - - try - { - $this->MailClient()->FolderDelete($sFolderFullNameRaw, - !!$this->Config()->Get('labs', 'use_imap_list_subscribe', true)); - } - catch (\MailSo\Mail\Exceptions\NonEmptyFolder $oException) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CantDeleteNonEmptyFolder, $oException); - } - catch (\Exception $oException) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CantDeleteFolder, $oException); - } - - return $this->TrueResponse(__FUNCTION__); - } - - /** - * @return array - * - * @throws \MailSo\Base\Exceptions\Exception - */ - public function DoFolderClear() - { - $this->initMailClientConnection(); - - $sFolderFullNameRaw = $this->GetActionParam('Folder', ''); - - try - { - $this->MailClient()->FolderClear($sFolderFullNameRaw); - } - catch (\Exception $oException) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::MailServerError, $oException); - } - - return $this->TrueResponse(__FUNCTION__); - } - - /** - * @return array - * - * @throws \MailSo\Base\Exceptions\Exception - */ - public function DoFolderInformation() - { - $sFolder = $this->GetActionParam('Folder', ''); - $sPrevUidNext = $this->GetActionParam('UidNext', ''); - $aFlagsUids = array(); - $sFlagsUids = (string) $this->GetActionParam('FlagsUids', ''); - - $aFlagsFilteredUids = array(); - if (0 < strlen($sFlagsUids)) - { - $aFlagsUids = explode(',', $sFlagsUids); - $aFlagsFilteredUids = array_filter($aFlagsUids, function (&$sUid) { - $sUid = (int) trim($sUid); - return 0 < (int) trim($sUid); - }); - } - - $this->initMailClientConnection(); - - $sForwardedFlag = $this->Config()->Get('labs', 'imap_forwarded_flag', ''); - $sReadReceiptFlag = $this->Config()->Get('labs', 'imap_read_receipt_flag', ''); - try - { - $aInboxInformation = $this->MailClient()->FolderInformation( - $sFolder, $sPrevUidNext, $aFlagsFilteredUids - ); - - if (\is_array($aInboxInformation) && isset($aInboxInformation['Flags']) && \is_array($aInboxInformation['Flags'])) - { - foreach ($aInboxInformation['Flags'] as $iUid => $aFlags) - { - $aLowerFlags = array_map('strtolower', $aFlags); - $aInboxInformation['Flags'][$iUid] = array( - 'IsSeen' => in_array('\\seen', $aLowerFlags), - 'IsFlagged' => in_array('\\flagged', $aLowerFlags), - 'IsAnswered' => in_array('\\answered', $aLowerFlags), - 'IsDeleted' => in_array('\\deleted', $aLowerFlags), - 'IsForwarded' => 0 < strlen($sForwardedFlag) && in_array(strtolower($sForwardedFlag), $aLowerFlags), - 'IsReadReceipt' => 0 < strlen($sReadReceiptFlag) && in_array(strtolower($sReadReceiptFlag), $aLowerFlags) - ); - } - } - } - catch (\Exception $oException) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::MailServerError, $oException); - } - - if (\is_array($aInboxInformation)) - { - $aInboxInformation['Version'] = APP_VERSION; - } - - return $this->DefaultResponse(__FUNCTION__, $aInboxInformation); - } - - /** - * @return array - * - * @throws \MailSo\Base\Exceptions\Exception - */ - public function DoFolderInformationMultiply() - { - $aResult = array( - 'List' => array(), - 'Version' => APP_VERSION - ); - - $aFolders = $this->GetActionParam('Folders', null); - if (\is_array($aFolders)) - { - $this->initMailClientConnection(); - - $aFolders = \array_unique($aFolders); - foreach ($aFolders as $sFolder) - { - if (0 < \strlen(\trim($sFolder)) && 'INBOX' !== \strtoupper($sFolder)) - { - try - { - $aInboxInformation = $this->MailClient()->FolderInformation($sFolder, '', array()); - if (\is_array($aInboxInformation) && isset($aInboxInformation['Folder'])) - { - $aResult['List'][] = $aInboxInformation; - } - } - catch (\Exception $oException) - { - $this->Logger()->WriteException($oException); - } - } - } - } - - return $this->DefaultResponse(__FUNCTION__, $aResult); - } - - /** - * @return array - * - * @throws \MailSo\Base\Exceptions\Exception - */ - public function DoMessageList() - { -// \sleep(1); -// throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CantGetMessageList); - - $sFolder = ''; - $iOffset = 0; - $iLimit = 20; - $sSearch = ''; - $sUidNext = ''; - $bUseThreads = false; - $sThreadUid = ''; - - $sRawKey = $this->GetActionParam('RawKey', ''); - $aValues = $this->getDecodedClientRawKeyValue($sRawKey, 9); - - if (\is_array($aValues) && 7 < \count($aValues)) - { - $sFolder =(string) $aValues[0]; - $iOffset = (int) $aValues[1]; - $iLimit = (int) $aValues[2]; - $sSearch = (string) $aValues[3]; - $sUidNext = (string) $aValues[6]; - $bUseThreads = (bool) $aValues[7]; - - if ($bUseThreads) - { - $sThreadUid = isset($aValues[8]) ? (string) $aValues[8] : ''; - } - - $this->verifyCacheByKey($sRawKey); - } - else - { - $sFolder = $this->GetActionParam('Folder', ''); - $iOffset = (int) $this->GetActionParam('Offset', 0); - $iLimit = (int) $this->GetActionParam('Limit', 10); - $sSearch = $this->GetActionParam('Search', ''); - $sUidNext = $this->GetActionParam('UidNext', ''); - $bUseThreads = '1' === (string) $this->GetActionParam('UseThreads', '0'); - - if ($bUseThreads) - { - $sThreadUid = (string) $this->GetActionParam('ThreadUid', ''); - } - } - - if (0 === strlen($sFolder)) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CantGetMessageList); - } - - $this->initMailClientConnection(); - - try - { - if (!$this->Config()->Get('labs', 'use_imap_thread', false)) - { - $bUseThreads = false; - } - - $oMessageList = $this->MailClient()->MessageList( - $sFolder, $iOffset, $iLimit, $sSearch, $sUidNext, - $this->cacherForUids(), - !!$this->Config()->Get('labs', 'use_imap_sort', false), - $bUseThreads, - $sThreadUid, - '' - ); - } - catch (\Exception $oException) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CantGetMessageList, $oException); - } - - if ($oMessageList instanceof \MailSo\Mail\MessageCollection) - { - $this->cacheByKey($sRawKey); - } - - return $this->DefaultResponse(__FUNCTION__, $oMessageList); - } - - /** - * @param \RainLoop\Model\Account $oAccount - * @param bool $bWithDraftInfo = true - * - * @return \MailSo\Mime\Message - */ - private function buildMessage($oAccount, $bWithDraftInfo = true) - { - $sIdentityID = $this->GetActionParam('IdentityID', ''); - $sTo = $this->GetActionParam('To', ''); - $sCc = $this->GetActionParam('Cc', ''); - $sBcc = $this->GetActionParam('Bcc', ''); - $sReplyTo = $this->GetActionParam('ReplyTo', ''); - $sSubject = $this->GetActionParam('Subject', ''); - $bTextIsHtml = '1' === $this->GetActionParam('TextIsHtml', '0'); - $bReadReceiptRequest = '1' === $this->GetActionParam('ReadReceiptRequest', '0'); - $bMarkAsImportant = '1' === $this->GetActionParam('MarkAsImportant', '0'); - $sText = $this->GetActionParam('Text', ''); - $aAttachments = $this->GetActionParam('Attachments', null); - - $aDraftInfo = $this->GetActionParam('DraftInfo', null); - $sInReplyTo = $this->GetActionParam('InReplyTo', ''); - $sReferences = $this->GetActionParam('References', ''); - - $oMessage = \MailSo\Mime\Message::NewInstance(); - - if (!$this->Config()->Get('security', 'hide_x_mailer_header', false)) - { - $oMessage->SetXMailer('RainLoop/'.APP_VERSION); - } - - $oFromIdentity = $this->GetIdentityByID($oAccount, $sIdentityID); - if ($oFromIdentity) - { - $oMessage->SetFrom(\MailSo\Mime\Email::NewInstance( - $oFromIdentity->Email(), $oFromIdentity->Name())); - } - else - { - $oMessage->SetFrom(\MailSo\Mime\Email::Parse($oAccount->Email())); - } - - $oFrom = $oMessage->GetFrom(); - $oMessage->RegenerateMessageId($oFrom ? $oFrom->GetDomain() : ''); - - if (!empty($sReplyTo)) - { - $oReplyTo = \MailSo\Mime\EmailCollection::NewInstance($sReplyTo); - if ($oReplyTo && 0 < $oReplyTo->Count()) - { - $oMessage->SetReplyTo($oReplyTo); - } - } - - if ($bReadReceiptRequest) - { - $oMessage->SetReadReceipt($oAccount->Email()); - } - - if ($bMarkAsImportant) - { - $oMessage->SetPriority(\MailSo\Mime\Enumerations\MessagePriority::HIGH); - } - - $oMessage->SetSubject($sSubject); - - $oToEmails = \MailSo\Mime\EmailCollection::NewInstance($sTo); - if ($oToEmails && $oToEmails->Count()) - { - $oMessage->SetTo($oToEmails); - } - - $oCcEmails = \MailSo\Mime\EmailCollection::NewInstance($sCc); - if ($oCcEmails && $oCcEmails->Count()) - { - $oMessage->SetCc($oCcEmails); - } - - $oBccEmails = \MailSo\Mime\EmailCollection::NewInstance($sBcc); - if ($oBccEmails && $oBccEmails->Count()) - { - $oMessage->SetBcc($oBccEmails); - } - - if ($bWithDraftInfo && \is_array($aDraftInfo) && !empty($aDraftInfo[0]) && !empty($aDraftInfo[1]) && !empty($aDraftInfo[2])) - { - $oMessage->SetDraftInfo($aDraftInfo[0], $aDraftInfo[1], $aDraftInfo[2]); - } - - if (0 < \strlen($sInReplyTo)) - { - $oMessage->SetInReplyTo($sInReplyTo); - } - - if (0 < \strlen($sReferences)) - { - $oMessage->SetReferences($sReferences); - } - - $aFoundedCids = array(); - $mFoundDataURL = array(); - $aFoundedContentLocationUrls = array(); - - $sTextToAdd = $bTextIsHtml ? - \MailSo\Base\HtmlUtils::BuildHtml($sText, $aFoundedCids, $mFoundDataURL, $aFoundedContentLocationUrls) : $sText; - - $this->Plugins()->RunHook($bTextIsHtml ? 'filter.message-html' : 'filter.message-plain', - array($oAccount, &$oMessage, &$sTextToAdd)); - - if ($bTextIsHtml && 0 < \strlen($sTextToAdd)) - { - $sTextConverted = \MailSo\Base\HtmlUtils::ConvertHtmlToPlain($sTextToAdd); - $this->Plugins()->RunHook('filter.message-plain', array($oAccount, &$oMessage, &$sTextConverted)); - $oMessage->AddText($sTextConverted, false); - } - - $oMessage->AddText($sTextToAdd, $bTextIsHtml); - - if (\is_array($aAttachments)) - { - foreach ($aAttachments as $sTempName => $aData) - { - $sFileName = (string) $aData[0]; - $bIsInline = (bool) $aData[1]; - $sCID = (string) $aData[2]; - $sContentLocation = isset($aData[3]) ? (string) $aData[3] : ''; - - $rResource = $this->FilesProvider()->GetFile($oAccount, $sTempName); - if (\is_resource($rResource)) - { - $iFileSize = $this->FilesProvider()->FileSize($oAccount, $sTempName); - - $oMessage->Attachments()->Add( - \MailSo\Mime\Attachment::NewInstance($rResource, $sFileName, $iFileSize, $bIsInline, - \in_array(trim(trim($sCID), '<>'), $aFoundedCids), - $sCID, array(), $sContentLocation - ) - ); - } - } - } - - if ($mFoundDataURL && \is_array($mFoundDataURL) && 0 < \count($mFoundDataURL)) - { - foreach ($mFoundDataURL as $sCidHash => $sDataUrlString) - { - $aMatch = array(); - $sCID = '<'.$sCidHash.'>'; - if (\preg_match('/^data:(image\/[a-zA-Z0-9]+);base64,(.+)$/i', $sDataUrlString, $aMatch) && - !empty($aMatch[1]) && !empty($aMatch[2])) - { - $sRaw = \MailSo\Base\Utils::Base64Decode($aMatch[2]); - $iFileSize = \strlen($sRaw); - if (0 < $iFileSize) - { - $sFileName = \preg_replace('/[^a-z0-9]+/i', '.', $aMatch[1]); - $rResource = \MailSo\Base\ResourceRegistry::CreateMemoryResourceFromString($sRaw); - - $sRaw = ''; - unset($sRaw); - unset($aMatch); - - $oMessage->Attachments()->Add( - \MailSo\Mime\Attachment::NewInstance($rResource, $sFileName, $iFileSize, true, true, $sCID) - ); - } - } - } - } - - $this->Plugins()->RunHook('filter.build-message', array(&$oMessage)); - $this->Plugins()->RunHook('filter.build-message[2]', array(&$oMessage, $oAccount)); - - return $oMessage; - } - - /** - * @param \RainLoop\Model\Account $oAccount - * - * @return void - */ - private function deleteMessageAttachmnets($oAccount) - { - $aAttachments = $this->GetActionParam('Attachments', null); - - if (\is_array($aAttachments)) - { - foreach (\array_keys($aAttachments) as $sTempName) - { - if ($this->FilesProvider()->FileExists($oAccount, $sTempName)) - { - $this->FilesProvider()->Clear($oAccount, $sTempName); - } - } - } - } - - /** - * @param \RainLoop\Model\Account $oAccount - * - * @return \MailSo\Mime\Message - */ - private function buildReadReceiptMessage($oAccount) - { - $sReadReceipt = $this->GetActionParam('ReadReceipt', ''); - $sSubject = $this->GetActionParam('Subject', ''); - $sText = $this->GetActionParam('Text', ''); - - $oIdentity = $this->GetAccountIdentity($oAccount); - - if (empty($sReadReceipt) || empty($sSubject) || empty($sText) || !$oIdentity) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::UnknownError); - } - - $oMessage = \MailSo\Mime\Message::NewInstance(); - - if (!$this->Config()->Get('security', 'hide_x_mailer_header', false)) - { - $oMessage->SetXMailer('RainLoop/'.APP_VERSION); - } - - $oMessage->SetFrom(\MailSo\Mime\Email::NewInstance($oIdentity->Email(), $oIdentity->Name())); - - $oFrom = $oMessage->GetFrom(); - $oMessage->RegenerateMessageId($oFrom ? $oFrom->GetDomain() : ''); - - $sReplyTo = $oIdentity->ReplyTo(); - if (!empty($sReplyTo)) - { - $oReplyTo = \MailSo\Mime\EmailCollection::NewInstance($sReplyTo); - if ($oReplyTo && $oReplyTo->Count()) - { - $oMessage->SetReplyTo($oReplyTo); - } - } - - $oMessage->SetSubject($sSubject); - - $oToEmails = \MailSo\Mime\EmailCollection::NewInstance($sReadReceipt); - if ($oToEmails && $oToEmails->Count()) - { - $oMessage->SetTo($oToEmails); - } - - $this->Plugins()->RunHook('filter.read-receipt-message-plain', array($oAccount, &$oMessage, &$sText)); - - $oMessage->AddText($sText, false); - - $this->Plugins()->RunHook('filter.build-read-receipt-message', array(&$oMessage, $oAccount)); - - return $oMessage; - } - - /** - * @return array - */ - public function DoSaveMessage() - { - $oAccount = $this->initMailClientConnection(); - - if (!$this->GetCapa(false, false, \RainLoop\Enumerations\Capa::COMPOSER, $oAccount)) - { - return $this->FalseResponse(__FUNCTION__); - } - - $sMessageFolder = $this->GetActionParam('MessageFolder', ''); - $sMessageUid = $this->GetActionParam('MessageUid', ''); - - $sDraftFolder = $this->GetActionParam('DraftFolder', ''); - if (0 === strlen($sDraftFolder)) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::UnknownError); - } - - $oMessage = $this->buildMessage($oAccount, true); - - $this->Plugins() - ->RunHook('filter.save-message', array(&$oMessage)) - ->RunHook('filter.save-message[2]', array(&$oMessage, $oAccount)) - ; - - $mResult = false; - if ($oMessage) - { - $rMessageStream = \MailSo\Base\ResourceRegistry::CreateMemoryResource(); - - $iMessageStreamSize = \MailSo\Base\Utils::MultipleStreamWriter( - $oMessage->ToStream(false), array($rMessageStream), 8192, true, true); - - if (false !== $iMessageStreamSize) - { - $sMessageId = $oMessage->MessageId(); - - \rewind($rMessageStream); - - $iNewUid = 0; - $this->MailClient()->MessageAppendStream( - $rMessageStream, $iMessageStreamSize, $sDraftFolder, array( - \MailSo\Imap\Enumerations\MessageFlag::SEEN - ), $iNewUid); - - if (!empty($sMessageId) && (null === $iNewUid || 0 === $iNewUid)) - { - $iNewUid = $this->MailClient()->FindMessageUidByMessageId($sDraftFolder, $sMessageId); - } - - $mResult = true; - - if (0 < strlen($sMessageFolder) && 0 < strlen($sMessageUid)) - { - $this->MailClient()->MessageDelete($sMessageFolder, array($sMessageUid), true, true); - } - - if (null !== $iNewUid && 0 < $iNewUid) - { - $mResult = array( - 'NewFolder' => $sDraftFolder, - 'NewUid' => $iNewUid - ); - } - } - } - - return $this->DefaultResponse(__FUNCTION__, $mResult); - } - - /** - * - * @param \RainLoop\Model\Account $oAccount - * @param \MailSo\Mime\Message $oMessage - * @param resource $rMessageStream - * @param bool $bDsn = false - * @param bool $bAddHiddenRcpt = true - * - * @throws \RainLoop\Exceptions\ClientException - * @throws \MailSo\Net\Exceptions\ConnectionException - */ - private function smtpSendMessage($oAccount, $oMessage, - &$rMessageStream, &$iMessageStreamSize, $bDsn = false, $bAddHiddenRcpt = true) - { - $oRcpt = $oMessage->GetRcpt(); - if ($oRcpt && 0 < $oRcpt->Count()) - { - $this->Plugins()->RunHook('filter.smtp-message-stream', - array($oAccount, &$rMessageStream, &$iMessageStreamSize)); - - $this->Plugins()->RunHook('filter.message-rcpt', array($oAccount, &$oRcpt)); - - try - { - $oFrom = $oMessage->GetFrom(); - $sFrom = $oFrom instanceof \MailSo\Mime\Email ? $oFrom->GetEmail() : ''; - $sFrom = empty($sFrom) ? $oAccount->Email() : $sFrom; - - $this->Plugins()->RunHook('filter.smtp-from', array($oAccount, $oMessage, &$sFrom)); - - $aHiddenRcpt = array(); - if ($bAddHiddenRcpt) - { - $this->Plugins()->RunHook('filter.smtp-hidden-rcpt', array($oAccount, $oMessage, &$aHiddenRcpt)); - } - - $bUsePhpMail = $oAccount->Domain()->OutUsePhpMail(); - - $oSmtpClient = \MailSo\Smtp\SmtpClient::NewInstance()->SetLogger($this->Logger()); - $oSmtpClient->SetTimeOuts(10, (int) \RainLoop\Api::Config()->Get('labs', 'smtp_timeout', 60)); - - $bLoggined = $oAccount->OutConnectAndLoginHelper($this->Plugins(), $oSmtpClient, $this->Config(), $bUsePhpMail); - - if ($bUsePhpMail) - { - if (\MailSo\Base\Utils::FunctionExistsAndEnabled('mail')) - { - $aToCollection = $oMessage->GetTo(); - if ($aToCollection && $oFrom) - { - $sRawBody = @\stream_get_contents($rMessageStream); - if (!empty($sRawBody)) - { - $sMailTo = \trim($aToCollection->ToString(true)); - $sMailSubject = \trim($oMessage->GetSubject()); - $sMailSubject = 0 === \strlen($sMailSubject) ? '' : \MailSo\Base\Utils::EncodeUnencodedValue( - \MailSo\Base\Enumerations\Encoding::BASE64_SHORT, $sMailSubject); - - $sMailHeaders = $sMailBody = ''; - list($sMailHeaders, $sMailBody) = \explode("\r\n\r\n", $sRawBody, 2); - unset($sRawBody); - - if ($this->Config()->Get('labs', 'mail_func_clear_headers', true)) - { - $sMailHeaders = \MailSo\Base\Utils::RemoveHeaderFromHeaders($sMailHeaders, array( - \MailSo\Mime\Enumerations\Header::TO_, - \MailSo\Mime\Enumerations\Header::SUBJECT - )); - } - - if ($this->Config()->Get('debug', 'enable', false)) - { - $this->Logger()->WriteDump(array( - $sMailTo, $sMailSubject, $sMailBody, $sMailHeaders - )); - } - - $bR = $this->Config()->Get('labs', 'mail_func_additional_parameters', false) ? - \mail($sMailTo, $sMailSubject, $sMailBody, $sMailHeaders, '-f'.$oFrom->GetEmail()) : - \mail($sMailTo, $sMailSubject, $sMailBody, $sMailHeaders); - - if (!$bR) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CantSendMessage); - } - } - } - } - else - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CantSendMessage); - } - } - else if ($oSmtpClient->IsConnected()) - { - if (!empty($sFrom)) - { - $oSmtpClient->MailFrom($sFrom, '', $bDsn); - } - - $aRcpt =& $oRcpt->GetAsArray(); - foreach ($aRcpt as /* @var $oEmail \MailSo\Mime\Email */ $oEmail) - { - $oSmtpClient->Rcpt($oEmail->GetEmail(), $bDsn); - } - - if ($bAddHiddenRcpt && \is_array($aHiddenRcpt) && 0 < \count($aHiddenRcpt)) - { - foreach ($aHiddenRcpt as $sEmail) - { - if (\preg_match('/^[^@\s]+@[^@\s]+$/', $sEmail)) - { - $oSmtpClient->Rcpt($sEmail); - } - } - } - - $oSmtpClient->DataWithStream($rMessageStream); - - if ($bLoggined) - { - $oSmtpClient->Logout(); - } - - $oSmtpClient->Disconnect(); - } - } - catch (\MailSo\Net\Exceptions\ConnectionException $oException) - { - if ($this->Config()->Get('labs', 'smtp_show_server_errors')) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::ClientViewError, $oException); - } - else - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::ConnectionError, $oException); - } - } - catch (\MailSo\Smtp\Exceptions\LoginException $oException) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::AuthError, $oException); - } - catch (\Exception $oException) - { - if ($this->Config()->Get('labs', 'smtp_show_server_errors')) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::ClientViewError, $oException); - } - else - { - throw $oException; - } - } - } - else - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::InvalidRecipients); - } - } - - /** - * @return array - */ - public function DoSendMessage() - { - $oAccount = $this->initMailClientConnection(); - - if (!$this->GetCapa(false, false, \RainLoop\Enumerations\Capa::COMPOSER, $oAccount)) - { - return $this->FalseResponse(__FUNCTION__); - } - - $oConfig = $this->Config(); - - $sDraftFolder = $this->GetActionParam('MessageFolder', ''); - $sDraftUid = $this->GetActionParam('MessageUid', ''); - $sSentFolder = $this->GetActionParam('SentFolder', ''); - $aDraftInfo = $this->GetActionParam('DraftInfo', null); - $bDsn = '1' === (string) $this->GetActionParam('Dsn', '0'); - - $oMessage = $this->buildMessage($oAccount, false); - - $this->Plugins() - ->RunHook('filter.send-message', array(&$oMessage)) - ->RunHook('filter.send-message[2]', array(&$oMessage, $oAccount)) - ; - - $mResult = false; - try - { - if ($oMessage) - { - $rMessageStream = \MailSo\Base\ResourceRegistry::CreateMemoryResource(); - - $iMessageStreamSize = \MailSo\Base\Utils::MultipleStreamWriter( - $oMessage->ToStream(true), array($rMessageStream), 8192, true, true, true); - - if (false !== $iMessageStreamSize) - { - $this->smtpSendMessage($oAccount, $oMessage, $rMessageStream, $iMessageStreamSize, $bDsn, true); - - if (\is_array($aDraftInfo) && 3 === \count($aDraftInfo)) - { - $sDraftInfoType = $aDraftInfo[0]; - $sDraftInfoUid = $aDraftInfo[1]; - $sDraftInfoFolder = $aDraftInfo[2]; - - try - { - switch (\strtolower($sDraftInfoType)) - { - case 'reply': - case 'reply-all': - $this->MailClient()->MessageSetFlag($sDraftInfoFolder, array($sDraftInfoUid), true, - \MailSo\Imap\Enumerations\MessageFlag::ANSWERED, true); - break; - case 'forward': - $sForwardedFlag = $this->Config()->Get('labs', 'imap_forwarded_flag', ''); - if (0 < strlen($sForwardedFlag)) - { - $this->MailClient()->MessageSetFlag($sDraftInfoFolder, array($sDraftInfoUid), true, - $sForwardedFlag, true); - } - break; - } - } - catch (\Exception $oException) - { - $this->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); - } - } - - if (0 < \strlen($sSentFolder)) - { - try - { - if (!$oMessage->GetBcc()) - { - if (\is_resource($rMessageStream)) - { - \rewind($rMessageStream); - } - - $this->Plugins()->RunHook('filter.sent-message-stream', - array($oAccount, &$rMessageStream, &$iMessageStreamSize)); - - $this->MailClient()->MessageAppendStream( - $rMessageStream, $iMessageStreamSize, $sSentFolder, array( - \MailSo\Imap\Enumerations\MessageFlag::SEEN - ) - ); - } - else - { - $rAppendMessageStream = \MailSo\Base\ResourceRegistry::CreateMemoryResource(); - - $iAppendMessageStreamSize = \MailSo\Base\Utils::MultipleStreamWriter( - $oMessage->ToStream(false), array($rAppendMessageStream), 8192, true, true, true); - - $this->Plugins()->RunHook('filter.sent-message-stream', - array($oAccount, &$rAppendMessageStream, &$iAppendMessageStreamSize)); - - $this->MailClient()->MessageAppendStream( - $rAppendMessageStream, $iAppendMessageStreamSize, $sSentFolder, array( - \MailSo\Imap\Enumerations\MessageFlag::SEEN - )); - - if (\is_resource($rAppendMessageStream)) - { - @fclose($rAppendMessageStream); - } - } - } - catch (\Exception $oException) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CantSaveMessage, $oException); - } - } - - if (\is_resource($rMessageStream)) - { - @\fclose($rMessageStream); - } - - $this->deleteMessageAttachmnets($oAccount); - - if (0 < \strlen($sDraftFolder) && 0 < \strlen($sDraftUid)) - { - try - { - $this->MailClient()->MessageDelete($sDraftFolder, array($sDraftUid), true, true); - } - catch (\Exception $oException) - { - $this->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); - } - } - - $mResult = true; - } - } - } - catch (\RainLoop\Exceptions\ClientException $oException) - { - throw $oException; - } - catch (\Exception $oException) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CantSendMessage, $oException); - } - - if (false === $mResult) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CantSendMessage); - } - - try - { - if ($oMessage && $this->AddressBookProvider($oAccount)->IsActive()) - { - $aArrayToFrec = array(); - $oToCollection = $oMessage->GetTo(); - if ($oToCollection) - { - $aTo =& $oToCollection->GetAsArray(); - foreach ($aTo as /* @var $oEmail \MailSo\Mime\Email */ $oEmail) - { - $aArrayToFrec[$oEmail->GetEmail(true)] = $oEmail->ToString(false, true); - } - } - - if (0 < \count($aArrayToFrec)) - { - $oSettings = $this->SettingsProvider()->Load($oAccount); - - $this->AddressBookProvider($oAccount)->IncFrec( - $oAccount->ParentEmailHelper(), \array_values($aArrayToFrec), - !!$oSettings->GetConf('ContactsAutosave', - !!$oConfig->Get('defaults', 'contacts_autosave', true))); - } - } - } - catch (\Exception $oException) - { - $this->Logger()->WriteException($oException); - } - - return $this->TrueResponse(__FUNCTION__); - } - - /** - * @return array - */ - public function DoSendReadReceiptMessage() - { - $oAccount = $this->initMailClientConnection(); - - if (!$this->GetCapa(false, false, \RainLoop\Enumerations\Capa::COMPOSER, $oAccount)) - { - return $this->FalseResponse(__FUNCTION__); - } - - $oMessage = $this->buildReadReceiptMessage($oAccount); - - $this->Plugins()->RunHook('filter.send-read-receipt-message', array(&$oMessage, $oAccount)); - - $mResult = false; - try - { - if ($oMessage) - { - $rMessageStream = \MailSo\Base\ResourceRegistry::CreateMemoryResource(); - - $iMessageStreamSize = \MailSo\Base\Utils::MultipleStreamWriter( - $oMessage->ToStream(true), array($rMessageStream), 8192, true, true, true); - - if (false !== $iMessageStreamSize) - { - $this->smtpSendMessage($oAccount, $oMessage, $rMessageStream, $iMessageStreamSize, false, false); - - if (\is_resource($rMessageStream)) - { - @\fclose($rMessageStream); - } - - $mResult = true; - - $sReadReceiptFlag = $this->Config()->Get('labs', 'imap_read_receipt_flag', ''); - if (!empty($sReadReceiptFlag)) - { - $sFolderFullName = $this->GetActionParam('MessageFolder', ''); - $sUid = $this->GetActionParam('MessageUid', ''); - - $this->Cacher($oAccount)->Set(\RainLoop\KeyPathHelper::ReadReceiptCache($oAccount->Email(), $sFolderFullName, $sUid), '1'); - - if (0 < \strlen($sFolderFullName) && 0 < \strlen($sUid)) - { - try - { - $this->MailClient()->MessageSetFlag($sFolderFullName, array($sUid), true, $sReadReceiptFlag, true, true); - } - catch (\Exception $oException) {} - } - } - } - } - } - catch (\RainLoop\Exceptions\ClientException $oException) - { - throw $oException; - } - catch (\Exception $oException) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CantSendMessage, $oException); - } - - if (false === $mResult) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CantSendMessage); - } - - return $this->TrueResponse(__FUNCTION__); - } - - /** - * @return array - */ - public function DoQuota() - { - $oAccount = $this->initMailClientConnection(); - - if (!$this->GetCapa(false, false, \RainLoop\Enumerations\Capa::QUOTA, $oAccount)) - { - return $this->DefaultResponse(__FUNCTION__, array(0, 0, 0, 0)); - } - - try - { - $aQuota = $this->MailClient()->Quota(); - } - catch (\Exception $oException) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::MailServerError, $oException); - } - - return $this->DefaultResponse(__FUNCTION__, $aQuota); - } - - private function getContactsSyncData($oAccount) - { - $mResult = null; - - $sData = $this->StorageProvider()->Get($oAccount, - \RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG, - 'contacts_sync' - ); - - if (!empty($sData)) - { - $mData = \RainLoop\Utils::DecodeKeyValues($sData); - if (\is_array($mData)) - { - $mResult = array( - 'Enable' => isset($mData['Enable']) ? !!$mData['Enable'] : false, - 'Url' => isset($mData['Url']) ? \trim($mData['Url']) : '', - 'User' => isset($mData['User']) ? \trim($mData['User']) : '', - 'Password' => isset($mData['Password']) ? $mData['Password'] : '' - ); - } - } - - return $mResult; - } - - /** - * @return array - */ - public function DoSaveContactsSyncData() - { - $oAccount = $this->getAccountFromToken(); - - $oAddressBookProvider = $this->AddressBookProvider($oAccount); - if (!$oAddressBookProvider || !$oAddressBookProvider->IsActive()) - { - return $this->FalseResponse(__FUNCTION__); - } - - $bEnabled = '1' === (string) $this->GetActionParam('Enable', '0'); - $sUrl = $this->GetActionParam('Url', ''); - $sUser = $this->GetActionParam('User', ''); - $sPassword = $this->GetActionParam('Password', ''); - - $mData = $this->getContactsSyncData($oAccount); - - $bResult = $this->StorageProvider()->Put($oAccount, - \RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG, - 'contacts_sync', - \RainLoop\Utils::EncodeKeyValues(array( - 'Enable' => $bEnabled, - 'User' => $sUser, - 'Password' => APP_DUMMY === $sPassword && isset($mData['Password']) ? - $mData['Password'] : (APP_DUMMY === $sPassword ? '' : $sPassword), - 'Url' => $sUrl - )) - ); - - return $this->DefaultResponse(__FUNCTION__, $bResult); - } - - /** - * @return array - */ - public function DoContactsSync() - { - $bResult = false; - $oAccount = $this->getAccountFromToken(); - - $oAddressBookProvider = $this->AddressBookProvider($oAccount); - if ($oAddressBookProvider && $oAddressBookProvider->IsActive()) - { - $mData = $this->getContactsSyncData($oAccount); - if (\is_array($mData) && isset($mData['Enable'], $mData['User'], $mData['Password'], $mData['Url']) && $mData['Enable']) - { - $bResult = $oAddressBookProvider->Sync( - $oAccount->ParentEmailHelper(), - $mData['Url'], $mData['User'], $mData['Password']); - } - } - - if (!$bResult) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::ContactsSyncError); - } - - return $this->TrueResponse(__FUNCTION__); - } - - private function getTwoFactorInfo($oAccount, $bRemoveSecret = false) - { - $sEmail = $oAccount->ParentEmailHelper(); - - $mData = null; - - $aResult = array( - 'User' => '', - 'IsSet' => false, - 'Enable' => false, - 'Secret' => '', - 'UrlTitle' => '', - 'BackupCodes' => '' - ); - - if (!empty($sEmail)) - { - $aResult['User'] = $sEmail; - - $sData = $this->StorageProvider()->Get($oAccount, - \RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG, - 'two_factor' - ); - - if ($sData) - { - $mData = \RainLoop\Utils::DecodeKeyValues($sData); - } - } - - if (\is_array($mData) && !empty($aResult['User']) && - !empty($mData['User']) && !empty($mData['Secret']) && - !empty($mData['BackupCodes']) && $sEmail === $mData['User']) - { - $aResult['IsSet'] = true; - $aResult['Enable'] = isset($mData['Enable']) ? !!$mData['Enable'] : false; - $aResult['Secret'] = $mData['Secret']; - $aResult['BackupCodes'] = $mData['BackupCodes']; - $aResult['UrlTitle'] = $this->Config()->Get('webmail', 'title', ''); - } - - if ($bRemoveSecret) - { - if (isset($aResult['Secret'])) - { - unset($aResult['Secret']); - } - - if (isset($aResult['UrlTitle'])) - { - unset($aResult['UrlTitle']); - } - - if (isset($aResult['BackupCodes'])) - { - unset($aResult['BackupCodes']); - } - } - - return $aResult; - } - - /** - * @param \RainLoop\Model\Account $oAccount - * @param string $sCode - * - * @return bool - */ - private function removeBackupCodeFromTwoFactorInfo($oAccount, $sCode) - { - if (!$oAccount || empty($sCode)) - { - return false; - } - - $sData = $this->StorageProvider()->Get($oAccount, - \RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG, - 'two_factor' - ); - - if ($sData) - { - $mData = \RainLoop\Utils::DecodeKeyValues($sData); - - if (!empty($mData['BackupCodes'])) - { - $sBackupCodes = \preg_replace('/[^\d]+/', ' ', ' '.$mData['BackupCodes'].' '); - $sBackupCodes = \str_replace(' '.$sCode.' ', '', $sBackupCodes); - - $mData['BackupCodes'] = \trim(\preg_replace('/[^\d]+/', ' ', $sBackupCodes)); - - return $this->StorageProvider()->Put($oAccount, - \RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG, - 'two_factor', - \RainLoop\Utils::EncodeKeyValues($mData) - ); - } - } - - return false; - } - - /** - * @return array - */ - public function DoGetTwoFactorInfo() - { - $oAccount = $this->getAccountFromToken(); - - if (!$this->TwoFactorAuthProvider()->IsActive() || - !$this->GetCapa(false, false, \RainLoop\Enumerations\Capa::TWO_FACTOR, $oAccount)) - { - return $this->FalseResponse(__FUNCTION__); - } - - return $this->DefaultResponse(__FUNCTION__, - $this->getTwoFactorInfo($oAccount, true)); - } - - /** - * @return array - */ - public function DoCreateTwoFactorSecret() - { - $oAccount = $this->getAccountFromToken(); - - if (!$this->TwoFactorAuthProvider()->IsActive() || - !$this->GetCapa(false, false, \RainLoop\Enumerations\Capa::TWO_FACTOR, $oAccount)) - { - return $this->FalseResponse(__FUNCTION__); - } - - $sEmail = $oAccount->ParentEmailHelper(); - - $sSecret = $this->TwoFactorAuthProvider()->CreateSecret(); - - $aCodes = array(); - for ($iIndex = 9; $iIndex > 0; $iIndex--) - { - $aCodes[] = \rand(100000000, 900000000); - } - - $this->StorageProvider()->Put($oAccount, - \RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG, - 'two_factor', - \RainLoop\Utils::EncodeKeyValues(array( - 'User' => $sEmail, - 'Enable' => false, - 'Secret' => $sSecret, - 'BackupCodes' => \implode(' ', $aCodes) - )) - ); - - $this->requestSleep(); - - return $this->DefaultResponse(__FUNCTION__, - $this->getTwoFactorInfo($oAccount)); - } - - /** - * @return array - */ - public function DoShowTwoFactorSecret() - { - $oAccount = $this->getAccountFromToken(); - - if (!$this->TwoFactorAuthProvider()->IsActive() || - !$this->GetCapa(false, false, \RainLoop\Enumerations\Capa::TWO_FACTOR, $oAccount)) - { - return $this->FalseResponse(__FUNCTION__); - } - - $aResult = $this->getTwoFactorInfo($oAccount); - if (\is_array($aResult)) - { - unset($aResult['BackupCodes']); - } - - return $this->DefaultResponse(__FUNCTION__, $aResult); - } - - /** - * @return array - */ - public function DoEnableTwoFactor() - { - $oAccount = $this->getAccountFromToken(); - - if (!$this->TwoFactorAuthProvider()->IsActive() || - !$this->GetCapa(false, false, \RainLoop\Enumerations\Capa::TWO_FACTOR, $oAccount)) - { - return $this->FalseResponse(__FUNCTION__); - } - - $sEmail = $oAccount->ParentEmailHelper(); - - $bResult = false; - $mData = $this->getTwoFactorInfo($oAccount); - if (isset($mData['Secret'], $mData['BackupCodes'])) - { - $bResult = $this->StorageProvider()->Put($oAccount, - \RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG, - 'two_factor', - \RainLoop\Utils::EncodeKeyValues(array( - 'User' => $sEmail, - 'Enable' => '1' === \trim($this->GetActionParam('Enable', '0')), - 'Secret' => $mData['Secret'], - 'BackupCodes' => $mData['BackupCodes'] - )) - ); - } - - return $this->DefaultResponse(__FUNCTION__, $bResult); - } - - /** - * @return array - */ - public function DoTestTwoFactorInfo() - { - $oAccount = $this->getAccountFromToken(); - - if (!$this->TwoFactorAuthProvider()->IsActive() || - !$this->GetCapa(false, false, \RainLoop\Enumerations\Capa::TWO_FACTOR, $oAccount)) - { - return $this->FalseResponse(__FUNCTION__); - } - - $sCode = \trim($this->GetActionParam('Code', '')); - - $aData = $this->getTwoFactorInfo($oAccount); - $sSecret = !empty($aData['Secret']) ? $aData['Secret'] : ''; - -// $this->Logger()->WriteDump(array( -// $sCode, $sSecret, $aData, -// $this->TwoFactorAuthProvider()->VerifyCode($sSecret, $sCode) -// )); - - $this->requestSleep(); - - return $this->DefaultResponse(__FUNCTION__, - $this->TwoFactorAuthProvider()->VerifyCode($sSecret, $sCode)); - } - - /** - * @return array - */ - public function DoClearTwoFactorInfo() - { - $oAccount = $this->getAccountFromToken(); - - if (!$this->TwoFactorAuthProvider()->IsActive() || - !$this->GetCapa(false, false, \RainLoop\Enumerations\Capa::TWO_FACTOR, $oAccount)) - { - return $this->FalseResponse(__FUNCTION__); - } - - $this->StorageProvider()->Clear($oAccount, - \RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG, - 'two_factor' - ); - - return $this->DefaultResponse(__FUNCTION__, - $this->getTwoFactorInfo($oAccount, true)); - } - - /** - * @return array - */ - public function DoContacts() - { - $oAccount = $this->getAccountFromToken(); - - $sSearch = \trim($this->GetActionParam('Search', '')); - $iOffset = (int) $this->GetActionParam('Offset', 0); - $iLimit = (int) $this->GetActionParam('Limit', 20); - $iOffset = 0 > $iOffset ? 0 : $iOffset; - $iLimit = 0 > $iLimit ? 20 : $iLimit; - - $iResultCount = 0; - $mResult = array(); - - $oAbp = $this->AddressBookProvider($oAccount); - if ($oAbp->IsActive()) - { - $iResultCount = 0; - $mResult = $oAbp->GetContacts($oAccount->ParentEmailHelper(), - $iOffset, $iLimit, $sSearch, $iResultCount); - } - - return $this->DefaultResponse(__FUNCTION__, array( - 'Offset' => $iOffset, - 'Limit' => $iLimit, - 'Count' => $iResultCount, - 'Search' => $sSearch, - 'List' => $mResult - )); - } - - /** - * @return array - */ - public function DoContactsDelete() - { - $oAccount = $this->getAccountFromToken(); - $aUids = \explode(',', (string) $this->GetActionParam('Uids', '')); - - $aFilteredUids = \array_filter($aUids, function (&$mUid) { - $mUid = (int) \trim($mUid); - return 0 < $mUid; - }); - - $bResult = false; - if (0 < \count($aFilteredUids) && $this->AddressBookProvider($oAccount)->IsActive()) - { - $bResult = $this->AddressBookProvider($oAccount)->DeleteContacts($oAccount->ParentEmailHelper(), $aFilteredUids); - } - - return $this->DefaultResponse(__FUNCTION__, $bResult); - } - - /** - * @return array - */ - public function DoContactSave() - { - $oAccount = $this->getAccountFromToken(); - - $bResult = false; - - $oAddressBookProvider = $this->AddressBookProvider($oAccount); - $sRequestUid = \trim($this->GetActionParam('RequestUid', '')); - if ($oAddressBookProvider && $oAddressBookProvider->IsActive() && 0 < \strlen($sRequestUid)) - { - $sUid = \trim($this->GetActionParam('Uid', '')); - - $oContact = null; - if (0 < \strlen($sUid)) - { - $oContact = $oAddressBookProvider->GetContactByID($oAccount->ParentEmailHelper(), $sUid); - } - - if (!$oContact) - { - $oContact = new \RainLoop\Providers\AddressBook\Classes\Contact(); - if (0 < \strlen($sUid)) - { - $oContact->IdContact = $sUid; - } - } - - $oContact->Properties = array(); - $aProperties = $this->GetActionParam('Properties', array()); - if (\is_array($aProperties)) - { - foreach ($aProperties as $aItem) - { - if ($aItem && isset($aItem[0], $aItem[1]) && \is_numeric($aItem[0])) - { - $oProp = new \RainLoop\Providers\AddressBook\Classes\Property(); - $oProp->Type = (int) $aItem[0]; - $oProp->Value = $aItem[1]; - $oProp->TypeStr = empty($aItem[2]) ? '': $aItem[2]; - - $oContact->Properties[] = $oProp; - } - } - } - - if (!empty($oContact->Etag)) - { - $oContact->Etag = \md5($oContact->ToVCard()); - } - - $oContact->PopulateDisplayAndFullNameValue(true); - - $bResult = $oAddressBookProvider->ContactSave($oAccount->ParentEmailHelper(), $oContact); - } - - return $this->DefaultResponse(__FUNCTION__, array( - 'RequestUid' => $sRequestUid, - 'ResultID' => $bResult ? $oContact->IdContact : '', - 'Result' => $bResult - )); - } - - /** - * @return array - */ - public function DoSuggestions() - { - $oAccount = $this->getAccountFromToken(); - - $sQuery = \trim($this->GetActionParam('Query', '')); - $iLimit = (int) $this->Config()->Get('contacts', 'suggestions_limit', 20); - - $aResult = array(); - - $this->Plugins()->RunHook('ajax.suggestions-input-parameters', array(&$sQuery, &$iLimit, $oAccount)); - - $iLimit = (int) $iLimit; - if (5 > $iLimit) - { - $iLimit = 5; - } - - $this->Plugins()->RunHook('ajax.suggestions-pre', array(&$aResult, $sQuery, $oAccount, $iLimit)); - - if ($iLimit > \count($aResult) && 0 < \strlen($sQuery)) - { - try - { - // Address Book - $oAddressBookProvider = $this->AddressBookProvider($oAccount); - if ($oAddressBookProvider && $oAddressBookProvider->IsActive()) - { - $aSuggestions = $oAddressBookProvider->GetSuggestions($oAccount->ParentEmailHelper(), $sQuery, $iLimit); - if (0 === \count($aResult)) - { - $aResult = $aSuggestions; - } - else - { - $aResult = \array_merge($aResult, $aSuggestions); - } - } - } - catch (\Exception $oException) - { - $this->Logger()->WriteException($oException); - } - } - - if ($iLimit > \count($aResult) && 0 < \strlen($sQuery)) - { - $oSuggestionsProvider = $this->SuggestionsProvider(); - if ($oSuggestionsProvider && $oSuggestionsProvider->IsActive()) - { - $aSuggestionsProviderResult = $oSuggestionsProvider->Process($oAccount, $sQuery, $iLimit); - if (\is_array($aSuggestionsProviderResult) && 0 < \count($aSuggestionsProviderResult)) - { - $aResult = \array_merge($aResult, $aSuggestionsProviderResult); - } - } - - } - - $aResult = \RainLoop\Utils::RemoveSuggestionDuplicates($aResult); - if ($iLimit < \count($aResult)) - { - $aResult = \array_slice($aResult, 0, $iLimit); - } - - $this->Plugins()->RunHook('ajax.suggestions-post', array(&$aResult, $sQuery, $oAccount, $iLimit)); - - $aResult = \RainLoop\Utils::RemoveSuggestionDuplicates($aResult); - if ($iLimit < \count($aResult)) - { - $aResult = \array_slice($aResult, 0, $iLimit); - } - - return $this->DefaultResponse(__FUNCTION__, $aResult); - } - - /** - * @return array - */ - private function messageSetFlag($sActionFunction, $sResponseFunction) - { - $this->initMailClientConnection(); - - $sFolder = $this->GetActionParam('Folder', ''); - $bSetAction = '1' === (string) $this->GetActionParam('SetAction', '0'); - $aUids = \explode(',', (string) $this->GetActionParam('Uids', '')); - $aFilteredUids = \array_filter($aUids, function (&$sUid) { - $sUid = (int) \trim($sUid); - return 0 < $sUid; - }); - - try - { - $this->MailClient()->{$sActionFunction}($sFolder, $aFilteredUids, true, $bSetAction, true); - } - catch (\Exception $oException) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::MailServerError, $oException); - } - - return $this->TrueResponse($sResponseFunction); - } - - /** - * @return array - */ - public function DoMessageSetSeen() - { - return $this->messageSetFlag('MessageSetSeen', __FUNCTION__); - } - - /** - * @return array - */ - public function DoMessageSetSeenToAll() - { - $this->initMailClientConnection(); - - $sFolder = $this->GetActionParam('Folder', ''); - $bSetAction = '1' === (string) $this->GetActionParam('SetAction', '0'); - $sThreadUids = \trim($this->GetActionParam('ThreadUids', '')); - - try - { - $this->MailClient()->MessageSetSeenToAll($sFolder, $bSetAction, - !empty($sThreadUids) ? explode(',', $sThreadUids) : null); - } - catch (\Exception $oException) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::MailServerError, $oException); - } - - return $this->TrueResponse(__FUNCTION__); - } - - /** - * @return array - */ - public function DoMessageSetFlagged() - { - return $this->messageSetFlag('MessageSetFlagged', __FUNCTION__); - } - - /** - * @return array - * - * @throws \MailSo\Base\Exceptions\Exception - */ - public function DoMessage() - { - $sRawKey = (string) $this->GetActionParam('RawKey', ''); - - $sFolder = ''; - $iUid = 0; - - $aValues = $this->getDecodedClientRawKeyValue($sRawKey, 4); - if (is_array($aValues) && 4 === count($aValues)) - { - $sFolder = (string) $aValues[0]; - $iUid = (int) $aValues[1]; - - $this->verifyCacheByKey($sRawKey); - } - else - { - $sFolder = $this->GetActionParam('Folder', ''); - $iUid = (int) $this->GetActionParam('Uid', 0); - } - - $oAccount = $this->initMailClientConnection(); - - try - { - $oMessage = $this->MailClient()->Message($sFolder, $iUid, true, - $this->cacherForThreads(), - (int) $this->Config()->Get('labs', 'imap_body_text_limit', 0) - ); - } - catch (\Exception $oException) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CantGetMessage, $oException); - } - - if ($oMessage instanceof \MailSo\Mail\Message) - { - $this->Plugins() - ->RunHook('filter.result-message', array(&$oMessage)) - ->RunHook('filter.result-message[2]', array(&$oMessage, $oAccount)) - ; - - $this->cacheByKey($sRawKey); - } - - return $this->DefaultResponse(__FUNCTION__, $oMessage); - } - - /** - * @return array - * - * @throws \MailSo\Base\Exceptions\Exception - */ - public function DoMessageDelete() - { - $this->initMailClientConnection(); - - $sFolder = $this->GetActionParam('Folder', ''); - $aUids = \explode(',', (string) $this->GetActionParam('Uids', '')); - - $aFilteredUids = \array_filter($aUids, function (&$sUid) { - $sUid = (int) \trim($sUid); - return 0 < $sUid; - }); - - try - { - $this->MailClient()->MessageDelete($sFolder, $aFilteredUids, true, true, - !!$this->Config()->Get('labs', 'use_imap_expunge_all_on_delete', false)); - } - catch (\Exception $oException) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CantDeleteMessage, $oException); - } - - if ($this->Config()->Get('labs', 'use_imap_unselect', true)) - { - try - { - $this->MailClient()->FolderUnSelect(); - } - catch (\Exception $oException) - { - unset($oException); - } - } - - $sHash = ''; - - try - { - $sHash = $this->MailClient()->FolderHash($sFolder); - } - catch (\Exception $oException) - { - unset($oException); - } - - return $this->DefaultResponse(__FUNCTION__, '' === $sHash ? false : array($sFolder, $sHash)); - } - - /** - * @return array - * - * @throws \MailSo\Base\Exceptions\Exception - */ - public function DoMessageMove() - { - $this->initMailClientConnection(); - - $sFromFolder = $this->GetActionParam('FromFolder', ''); - $sToFolder = $this->GetActionParam('ToFolder', ''); - $aUids = \explode(',', (string) $this->GetActionParam('Uids', '')); - $bMarkAsRead = '1' === (string) $this->GetActionParam('MarkAsRead', '0'); - - $aFilteredUids = \array_filter($aUids, function (&$mUid) { - $mUid = (int) \trim($mUid); - return 0 < $mUid; - }); - - if ($bMarkAsRead) - { - try - { - $this->MailClient()->MessageSetSeen($sFromFolder, $aFilteredUids, true, true); - } - catch (\Exception $oException) - { - unset($oException); - } - } - - try - { - $this->MailClient()->MessageMove($sFromFolder, $sToFolder, $aFilteredUids, true, - !!$this->Config()->Get('labs', 'use_imap_move', true), - !!$this->Config()->Get('labs', 'use_imap_expunge_all_on_delete', false) - ); - } - catch (\Exception $oException) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CantMoveMessage, $oException); - } - - if ($this->Config()->Get('labs', 'use_imap_unselect', true)) - { - try - { - $this->MailClient()->FolderUnSelect(); - } - catch (\Exception $oException) - { - unset($oException); - } - } - - $sHash = ''; - - try - { - $sHash = $this->MailClient()->FolderHash($sFromFolder); - } - catch (\Exception $oException) - { - unset($oException); - } - - return $this->DefaultResponse(__FUNCTION__, '' === $sHash ? false : array($sFromFolder, $sHash)); - } - - /** - * @return array - * - * @throws \MailSo\Base\Exceptions\Exception - */ - public function DoMessageCopy() - { - $this->initMailClientConnection(); - - $sFromFolder = $this->GetActionParam('FromFolder', ''); - $sToFolder = $this->GetActionParam('ToFolder', ''); - $aUids = \explode(',', (string) $this->GetActionParam('Uids', '')); - - $aFilteredUids = \array_filter($aUids, function (&$mUid) { - $mUid = (int) \trim($mUid); - return 0 < $mUid; - }); - - try - { - $this->MailClient()->MessageCopy($sFromFolder, $sToFolder, - $aFilteredUids, true); - - $sHash = $this->MailClient()->FolderHash($sFromFolder); - } - catch (\Exception $oException) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CantCopyMessage, $oException); - } - - return $this->DefaultResponse(__FUNCTION__, - '' === $sHash ? false : array($sFromFolder, $sHash)); - } - - /** - * @param string $sFileName - * @param string $sContentType - * @param string $sMimeIndex - * @param int $iMaxLength = 250 - * - * @return string - */ - public function MainClearFileName($sFileName, $sContentType, $sMimeIndex, $iMaxLength = 250) - { - $sFileName = 0 === \strlen($sFileName) ? \preg_replace('/[^a-zA-Z0-9]/', '.', (empty($sMimeIndex) ? '' : $sMimeIndex.'.').$sContentType) : $sFileName; - $sClearedFileName = \MailSo\Base\Utils::StripSpaces(\preg_replace('/[\.]+/', '.', $sFileName)); - $sExt = \MailSo\Base\Utils::GetFileExtension($sClearedFileName); - - if (10 < $iMaxLength && $iMaxLength < \strlen($sClearedFileName) - \strlen($sExt)) - { - $sClearedFileName = \substr($sClearedFileName, 0, $iMaxLength).(empty($sExt) ? '' : '.'.$sExt); - } - - return \MailSo\Base\Utils::ClearFileName(\MailSo\Base\Utils::Utf8Clear($sClearedFileName)); - } - - /** - * @return array - */ - public function DoMessageUploadAttachments() - { - $oAccount = $this->initMailClientConnection(); - - $mResult = false; - $self = $this; - - try - { - $aAttachments = $this->GetActionParam('Attachments', array()); - if (\is_array($aAttachments) && 0 < \count($aAttachments)) - { - $mResult = array(); - foreach ($aAttachments as $sAttachment) - { - $aValues = \RainLoop\Utils::DecodeKeyValuesQ($sAttachment); - if (\is_array($aValues)) - { - $sFolder = isset($aValues['Folder']) ? $aValues['Folder'] : ''; - $iUid = (int) isset($aValues['Uid']) ? $aValues['Uid'] : 0; - $sMimeIndex = (string) isset($aValues['MimeIndex']) ? $aValues['MimeIndex'] : ''; - - $sTempName = \md5($sAttachment); - if (!$this->FilesProvider()->FileExists($oAccount, $sTempName)) - { - $this->MailClient()->MessageMimeStream( - function($rResource, $sContentType, $sFileName, $sMimeIndex = '') use ($oAccount, &$mResult, $sTempName, $sAttachment, $self) { - if (is_resource($rResource)) - { - $sContentType = (empty($sFileName)) ? 'text/plain' : \MailSo\Base\Utils::MimeContentType($sFileName); - $sFileName = $self->MainClearFileName($sFileName, $sContentType, $sMimeIndex); - - if ($self->FilesProvider()->PutFile($oAccount, $sTempName, $rResource)) - { - $mResult[$sTempName] = $sAttachment; - } - } - }, $sFolder, $iUid, true, $sMimeIndex); - } - else - { - $mResult[$sTempName] = $sAttachment; - } - } - } - } - } - catch (\Exception $oException) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::MailServerError, $oException); - } - - return $this->DefaultResponse(__FUNCTION__, $mResult); - } - - /** - * @return array - */ - public function DoComposeUploadExternals() - { - $oAccount = $this->getAccountFromToken(); - - $mResult = false; - $aExternals = $this->GetActionParam('Externals', array()); - if (\is_array($aExternals) && 0 < \count($aExternals)) - { - $oHttp = \MailSo\Base\Http::SingletonInstance(); - - $mResult = array(); - foreach ($aExternals as $sUrl) - { - $mResult[$sUrl] = ''; - - $sTempName = \md5($sUrl); - - $iCode = 0; - $sContentType = ''; - - $rFile = $this->FilesProvider()->GetFile($oAccount, $sTempName, 'wb+'); - if ($rFile && $oHttp->SaveUrlToFile($sUrl, $rFile, '', $sContentType, $iCode, $this->Logger(), 60, - $this->Config()->Get('labs', 'curl_proxy', ''), $this->Config()->Get('labs', 'curl_proxy_auth', ''))) - { - $mResult[$sUrl] = $sTempName; - } - - if (\is_resource($rFile)) - { - @\fclose($rFile); - } - } - } - - return $this->DefaultResponse(__FUNCTION__, $mResult); - } - - /** - * @return array - */ - public function DoComposeUploadDrive() - { - $oAccount = $this->getAccountFromToken(); - - $mResult = false; - - $sUrl = $this->GetActionParam('Url', ''); - $sAccessToken = $this->GetActionParam('AccessToken', ''); - $sGoogleApiKey = (string) $this->Config()->Get('social', 'google_api_key', ''); - - if (0 < \strlen($sUrl) && 0 < \strlen($sAccessToken) && 0 < \strlen($sGoogleApiKey)) - { - $oHttp = \MailSo\Base\Http::SingletonInstance(); - - $mResult[$sUrl] = false; - - $sTempName = \md5($sUrl); - - $iCode = 0; - $sContentType = ''; - - $rFile = $this->FilesProvider()->GetFile($oAccount, $sTempName, 'wb+'); - if ($rFile && $oHttp->SaveUrlToFile($sUrl.'&key='.$sGoogleApiKey, $rFile, '', $sContentType, $iCode, $this->Logger(), 60, - $this->Config()->Get('labs', 'curl_proxy', ''), $this->Config()->Get('labs', 'curl_proxy_auth', ''), - array('Authorization: Bearer '.$sAccessToken))) - { - $mResult[$sUrl] = array($sTempName, 0); - } - - if (\is_resource($rFile)) - { - @\fclose($rFile); - } - - if (isset($mResult[$sUrl][1])) - { - $mResult[$sUrl][1] = $rFile = $this->FilesProvider()->FileSize($oAccount, $sTempName); - } - } - - return $this->DefaultResponse(__FUNCTION__, $mResult); - } - - /** - * @return array - */ - public function DoSocialUsers() - { - $oAccount = $this->getAccountFromToken(); - - $oSettings = $this->SettingsProvider()->Load($oAccount); - - $aData = array( - 'Google' => '', - 'Facebook' => '', - 'Twitter' => '' - ); - - if ($oSettings) - { - $aData['Google'] = $oSettings->GetConf('GoogleSocialName', ''); - $aData['Facebook'] = $oSettings->GetConf('FacebookSocialName', ''); - $aData['Twitter'] = $oSettings->GetConf('TwitterSocialName', ''); - } - - return $this->DefaultResponse(__FUNCTION__, $aData); - } - - /** - * @return array - */ - public function DoSocialGoogleDisconnect() - { - $oAccount = $this->getAccountFromToken(); - return $this->DefaultResponse(__FUNCTION__, $this->Social()->GoogleDisconnect($oAccount)); - } - - /** - * @return array - */ - public function DoSocialTwitterDisconnect() - { - $oAccount = $this->getAccountFromToken(); - return $this->DefaultResponse(__FUNCTION__, $this->Social()->TwitterDisconnect($oAccount)); - } - - /** - * @return array - */ - public function DoSocialFacebookDisconnect() - { - $oAccount = $this->getAccountFromToken(); - return $this->DefaultResponse(__FUNCTION__, $this->Social()->FacebookDisconnect($oAccount)); - } - - /** - * @param int $iError - * @param int $iClientError - * - * @return string - */ - private function getUploadErrorMessageByCode($iError, &$iClientError) - { - $sError = ''; - $iClientError = UploadClientError::NORMAL; - switch($iError) - { - case UPLOAD_ERR_OK: - break; - case UPLOAD_ERR_INI_SIZE: - case UPLOAD_ERR_FORM_SIZE: - case UploadError::CONFIG_SIZE: - case UploadError::EMPTY_FILES_DATA: - $sError = 'File is too big'; - $iClientError = UploadClientError::FILE_IS_TOO_BIG; - break; - case UPLOAD_ERR_PARTIAL: - $sError = 'File partially uploaded'; - $iClientError = UploadClientError::FILE_PARTIALLY_UPLOADED; - break; - case UPLOAD_ERR_NO_FILE: - $sError = 'No file uploaded'; - $iClientError = UploadClientError::FILE_NO_UPLOADED; - break; - case UPLOAD_ERR_NO_TMP_DIR: - case UPLOAD_ERR_CANT_WRITE: - case UPLOAD_ERR_EXTENSION: - $sError = 'Missing temp folder'; - $iClientError = UploadClientError::MISSING_TEMP_FOLDER; - break; - case UploadError::ON_SAVING: - $sError = 'Error on saving file'; - $iClientError = UploadClientError::FILE_ON_SAVING_ERROR; - break; - case UploadError::FILE_TYPE: - $sError = 'Invalid file type'; - $iClientError = UploadClientError::FILE_TYPE; - break; - case UploadError::UNKNOWN: - default: - $sError = 'Unknown error'; - $iClientError = UploadClientError::UNKNOWN; - break; - } - - return $sError; - } - - /** - * @return array - */ - public function Upload() - { - $oAccount = $this->getAccountFromToken(); - - $aResponse = array(); - - $aFile = $this->GetActionParam('File', null); - $iError = $this->GetActionParam('Error', \RainLoop\Enumerations\UploadError::UNKNOWN); - - if ($oAccount && UPLOAD_ERR_OK === $iError && \is_array($aFile)) - { - $sSavedName = 'upload-post-'.\md5($aFile['name'].$aFile['tmp_name']); - if (!$this->FilesProvider()->MoveUploadedFile($oAccount, $sSavedName, $aFile['tmp_name'])) - { - $iError = \RainLoop\Enumerations\UploadError::ON_SAVING; - } - else - { - $sUploadName = $aFile['name']; - $iSize = $aFile['size']; - $sMimeType = $aFile['type']; - - $aResponse['Attachment'] = array( - 'Name' => $sUploadName, - 'TempName' => $sSavedName, - 'MimeType' => $sMimeType, - 'Size' => (int) $iSize - ); - } - } - - if (UPLOAD_ERR_OK !== $iError) - { - $iClientError = \RainLoop\Enumerations\UploadClientError::NORMAL; - $sError = $this->getUploadErrorMessageByCode($iError, $iClientError); - - if (!empty($sError)) - { - $aResponse['ErrorCode'] = $iClientError; - $aResponse['Error'] = $sError; - } - } - - return $this->DefaultResponse(__FUNCTION__, $aResponse); - } - - /** - * @return array - */ - public function DoClearUserBackground() - { - $oAccount = $this->getAccountFromToken(); - - if (!$this->GetCapa(false, false, \RainLoop\Enumerations\Capa::USER_BACKGROUND, $oAccount)) - { - return $this->FalseResponse(__FUNCTION__); - } - - $oSettings = $this->SettingsProvider()->Load($oAccount); - if ($oAccount && $oSettings) - { - $this->StorageProvider()->Clear($oAccount, - \RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG, - 'background' - ); - - $oSettings->SetConf('UserBackgroundName', ''); - $oSettings->SetConf('UserBackgroundHash', ''); - } - - return $this->DefaultResponse(__FUNCTION__, $oAccount && $oSettings ? - $this->SettingsProvider()->Save($oAccount, $oSettings) : false); - } - - /** - * @return array - */ - public function UploadBackground() - { - $oAccount = $this->getAccountFromToken(); - - if (!$this->GetCapa(false, false, \RainLoop\Enumerations\Capa::USER_BACKGROUND, $oAccount)) - { - return $this->FalseResponse(__FUNCTION__); - } - - $sName = ''; - $sHash = ''; - - $aFile = $this->GetActionParam('File', null); - $iError = $this->GetActionParam('Error', \RainLoop\Enumerations\UploadError::UNKNOWN); - - if ($oAccount && UPLOAD_ERR_OK === $iError && \is_array($aFile)) - { - $sMimeType = \strtolower(\MailSo\Base\Utils::MimeContentType($aFile['name'])); - if (\in_array($sMimeType, array('image/png', 'image/jpg', 'image/jpeg'))) - { - $sSavedName = 'upload-post-'.\md5($aFile['name'].$aFile['tmp_name']); - if (!$this->FilesProvider()->MoveUploadedFile($oAccount, $sSavedName, $aFile['tmp_name'])) - { - $iError = \RainLoop\Enumerations\UploadError::ON_SAVING; - } - else - { - $rData = $this->FilesProvider()->GetFile($oAccount, $sSavedName); - if (@\is_resource($rData)) - { - $sData = @\stream_get_contents($rData); - if (!empty($sData) && 0 < \strlen($sData)) - { - $sName = $aFile['name']; - if (empty($sName)) - { - $sName = '_'; - } - - if ($this->StorageProvider()->Put($oAccount, - \RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG, - 'background', - \json_encode(array( - 'Name' => $aFile['name'], - 'ContentType' => $sMimeType, - 'Raw' => \base64_encode($sData) - )) - )) - { - $oSettings = $this->SettingsProvider()->Load($oAccount); - if ($oSettings) - { - $sHash = \MailSo\Base\Utils::Md5Rand($sName.APP_VERSION.APP_SALT); - - $oSettings->SetConf('UserBackgroundName', $sName); - $oSettings->SetConf('UserBackgroundHash', $sHash); - $this->SettingsProvider()->Save($oAccount, $oSettings); - } - } - } - - unset($sData); - } - - if (@\is_resource($rData)) - { - @\fclose($rData); - } - - unset($rData); - } - - $this->FilesProvider()->Clear($oAccount, $sSavedName); - } - else - { - $iError = \RainLoop\Enumerations\UploadError::FILE_TYPE; - } - } - - if (UPLOAD_ERR_OK !== $iError) - { - $iClientError = \RainLoop\Enumerations\UploadClientError::NORMAL; - $sError = $this->getUploadErrorMessageByCode($iError, $iClientError); - - if (!empty($sError)) - { - return $this->FalseResponse(__FUNCTION__, $iClientError, $sError); - } - } - - return $this->DefaultResponse(__FUNCTION__, !empty($sName) && !empty($sHash) ? array( - 'Name' => $sName, - 'Hash' => $sHash - ) : false); - } - - /** - * @return array - */ - public function UploadContacts() - { - $oAccount = $this->getAccountFromToken(); - - $mResponse = false; - - $aFile = $this->GetActionParam('File', null); - $iError = $this->GetActionParam('Error', \RainLoop\Enumerations\UploadError::UNKNOWN); - - if ($oAccount && UPLOAD_ERR_OK === $iError && \is_array($aFile)) - { - $sSavedName = 'upload-post-'.\md5($aFile['name'].$aFile['tmp_name']); - if (!$this->FilesProvider()->MoveUploadedFile($oAccount, $sSavedName, $aFile['tmp_name'])) - { - $iError = \RainLoop\Enumerations\UploadError::ON_SAVING; - } - else - { - @\ini_set('auto_detect_line_endings', true); - $mData = $this->FilesProvider()->GetFile($oAccount, $sSavedName); - if ($mData) - { - $sFileStart = @\fread($mData, 20); - \rewind($mData); - - if (false !== $sFileStart) - { - $sFileStart = \trim($sFileStart); - if (false !== \strpos($sFileStart, 'BEGIN:VCARD')) - { - $mResponse = $this->importContactsFromVcfFile($oAccount, $mData); - } - else if (false !== \strpos($sFileStart, ',') || false !== \strpos($sFileStart, ';')) - { - $mResponse = $this->importContactsFromCsvFile($oAccount, $mData, $sFileStart); - } - } - } - - if (\is_resource($mData)) - { - @\fclose($mData); - } - - unset($mData); - $this->FilesProvider()->Clear($oAccount, $sSavedName); - - @\ini_set('auto_detect_line_endings', false); - } - } - - if (UPLOAD_ERR_OK !== $iError) - { - $iClientError = \RainLoop\Enumerations\UploadClientError::NORMAL; - $sError = $this->getUploadErrorMessageByCode($iError, $iClientError); - - if (!empty($sError)) - { - return $this->FalseResponse(__FUNCTION__, $iClientError, $sError); - } - } - - return $this->DefaultResponse(__FUNCTION__, $mResponse); - } - - /** - * @param \RainLoop\Model\Account $oAccount - * @param resource $rFile - * @param string $sFileStart - * - * @return int - */ - private function importContactsFromCsvFile($oAccount, $rFile, $sFileStart) - { - $iCount = 0; - $aHeaders = null; - $aData = array(); - - if ($oAccount && \is_resource($rFile)) - { - $oAddressBookProvider = $this->AddressBookProvider($oAccount); - if ($oAddressBookProvider && $oAddressBookProvider->IsActive()) - { - $sDelimiter = ((int) \strpos($sFileStart, ',') > (int) \strpos($sFileStart, ';')) ? ',' : ';'; - - @\setlocale(LC_CTYPE, 'en_US.UTF-8'); - while (false !== ($mRow = \fgetcsv($rFile, 5000, $sDelimiter, '"'))) - { - if (null === $aHeaders) - { - if (3 >= \count($mRow)) - { - return 0; - } - - $aHeaders = $mRow; - - foreach ($aHeaders as $iIndex => $sHeaderValue) - { - $aHeaders[$iIndex] = \MailSo\Base\Utils::Utf8Clear($sHeaderValue); - } - } - else - { - $aNewItem = array(); - foreach ($aHeaders as $iIndex => $sHeaderValue) - { - $aNewItem[$sHeaderValue] = isset($mRow[$iIndex]) ? $mRow[$iIndex] : ''; - } - - $aData[] = $aNewItem; - } - } - - if (\is_array($aData) && 0 < \count($aData)) - { - $this->Logger()->Write('Import contacts from csv'); - $iCount = $oAddressBookProvider->ImportCsvArray($oAccount->ParentEmailHelper(), $aData); - } - } - } - - return $iCount; - } - - /** - * @param \RainLoop\Model\Account $oAccount - * @param resource $rFile - * - * @return int - */ - private function importContactsFromVcfFile($oAccount, $rFile) - { - $iCount = 0; - if ($oAccount && \is_resource($rFile)) - { - $oAddressBookProvider = $this->AddressBookProvider($oAccount); - if ($oAddressBookProvider && $oAddressBookProvider->IsActive()) - { - $sFile = \stream_get_contents($rFile); - if (\is_resource($rFile)) - { - \fclose($rFile); - } - - if (is_string($sFile) && 5 < \strlen($sFile)) - { - $this->Logger()->Write('Import contacts from vcf'); - $iCount = $oAddressBookProvider->ImportVcfFile($oAccount->ParentEmailHelper(), $sFile); - } - } - } - - return $iCount; - } - - /** - * @return bool - * - * @throws \MailSo\Base\Exceptions\Exception - */ - public function RawViewAsPlain() - { - $this->initMailClientConnection(); - - $sRawKey = (string) $this->GetActionParam('RawKey', ''); - $aValues = $this->getDecodedRawKeyValue($sRawKey); - - $sFolder = isset($aValues['Folder']) ? $aValues['Folder'] : ''; - $iUid = (int) (isset($aValues['Uid']) ? $aValues['Uid'] : 0); - $sMimeIndex = (string) (isset($aValues['MimeIndex']) ? $aValues['MimeIndex'] : ''); - - \header('Content-Type: text/plain', true); - - return $this->MailClient()->MessageMimeStream(function ($rResource) { - if (\is_resource($rResource)) - { - \MailSo\Base\Utils::FpassthruWithTimeLimitReset($rResource); - } - }, $sFolder, $iUid, true, $sMimeIndex); - } - - /** - * @return string - */ - public function RawFramedView() - { - $oAccount = $this->getAccountFromToken(false); - if ($oAccount) - { - $sRawKey = (string) $this->GetActionParam('RawKey', ''); - $aParams = $this->GetActionParam('Params', null); - $this->Http()->ServerNoCache(); - - $aData = \RainLoop\Utils::DecodeKeyValuesQ($sRawKey); - if (isset($aParams[0], $aParams[1], $aParams[2]) && - 'Raw' === $aParams[0] && 'FramedView' === $aParams[2] && isset($aData['Framed']) && $aData['Framed'] && $aData['FileName']) - { - if ($this->isFileHasFramedPreview($aData['FileName'])) - { - $sNewSpecAuthToken = $this->GetShortLifeSpecAuthToken(); - if (!empty($sNewSpecAuthToken)) - { - $aParams[1] = '_'.$sNewSpecAuthToken; - $aParams[2] = 'View'; - - \array_shift($aParams); - $sLast = \array_pop($aParams); - - $sUrl = $this->Http()->GetFullUrl().'?/Raw/&q[]=/'.\implode('/', $aParams).'/&q[]=/'.$sLast; - $sFullUrl = 'https://docs.google.com/viewer?embedded=true&url='.\urlencode($sUrl); - - @\header('Content-Type: text/html; charset=utf-8'); - echo ''. - ''. - ''. - ''; - } - } - } - } - - - return true; - - } - - /** - * @return bool - * - * @throws \MailSo\Base\Exceptions\Exception - */ - public function Append() - { - $oAccount = $this->initMailClientConnection(); - - $sFolderFullNameRaw = $this->GetActionParam('Folder', ''); - - $_FILES = isset($_FILES) ? $_FILES : null; - if ($oAccount instanceof \RainLoop\Model\Account && - $this->Config()->Get('labs', 'allow_message_append', false) && - isset($_FILES, $_FILES['AppendFile'], $_FILES['AppendFile']['name'], - $_FILES['AppendFile']['tmp_name'], $_FILES['AppendFile']['size'])) - { - if (is_string($_FILES['AppendFile']['tmp_name']) && 0 < strlen($_FILES['AppendFile']['tmp_name'])) - { - if (\UPLOAD_ERR_OK === (int) $_FILES['AppendFile']['error'] && !empty($sFolderFullNameRaw)) - { - $sSavedName = 'append-post-'.md5($sFolderFullNameRaw.$_FILES['AppendFile']['name'].$_FILES['AppendFile']['tmp_name']); - - if ($this->FilesProvider()->MoveUploadedFile($oAccount, - $sSavedName, $_FILES['AppendFile']['tmp_name'])) - { - $iMessageStreamSize = $this->FilesProvider()->FileSize($oAccount, $sSavedName); - $rMessageStream = $this->FilesProvider()->GetFile($oAccount, $sSavedName); - - $this->MailClient()->MessageAppendStream($rMessageStream, $iMessageStreamSize, $sFolderFullNameRaw); - - $this->FilesProvider()->Clear($oAccount, $sSavedName); - } - } - } - } - - return $this->DefaultResponse(__FUNCTION__, true); - } - - /** - * @param bool $bAdmin - * @param bool $bMobile = false - * @param \RainLoop\Model\Account $oAccount = null - * - * @return array - */ - public function Capa($bAdmin, $bMobile = false, $oAccount = null) - { - $oConfig = $this->Config(); - - $aResult = array(); - - if ($oConfig->Get('capa', 'folders', true)) - { - $aResult[] = \RainLoop\Enumerations\Capa::FOLDERS; - - if ($oConfig->Get('capa', 'messagelist_actions', true)) - { - $aResult[] = \RainLoop\Enumerations\Capa::MESSAGELIST_ACTIONS; - - if ($oConfig->Get('capa', 'dangerous_actions', true)) - { - $aResult[] = \RainLoop\Enumerations\Capa::DANGEROUS_ACTIONS; - } - } - } - - if ($oConfig->Get('capa', 'reload', true)) - { - $aResult[] = \RainLoop\Enumerations\Capa::RELOAD; - } - - if ($oConfig->Get('capa', 'quota', true)) - { - $aResult[] = \RainLoop\Enumerations\Capa::QUOTA; - } - - if ($oConfig->Get('capa', 'settings', true)) - { - $aResult[] = \RainLoop\Enumerations\Capa::SETTINGS; - - if ($oConfig->Get('webmail', 'allow_additional_accounts', false)) - { - $aResult[] = \RainLoop\Enumerations\Capa::ADDITIONAL_ACCOUNTS; - } - - if ($oConfig->Get('webmail', 'allow_additional_identities', false)) - { - $aResult[] = \RainLoop\Enumerations\Capa::IDENTITIES; - } - - if ($oConfig->Get('capa', 'x-templates', true) && !$bMobile) - { - $aResult[] = \RainLoop\Enumerations\Capa::TEMPLATES; - } - - if ($oConfig->Get('webmail', 'allow_themes', false) && !$bMobile) - { - $aResult[] = \RainLoop\Enumerations\Capa::THEMES; - } - - if ($oConfig->Get('webmail', 'allow_user_background', false) && !$bMobile) - { - $aResult[] = \RainLoop\Enumerations\Capa::USER_BACKGROUND; - } - - if ($oConfig->Get('security', 'openpgp', false) && !$bMobile) - { - $aResult[] = \RainLoop\Enumerations\Capa::OPEN_PGP; - } - - if ($oConfig->Get('capa', 'filters', false)) - { - $aResult[] = \RainLoop\Enumerations\Capa::FILTERS; - if ($bAdmin || ($oAccount && $oAccount->Domain()->UseSieve())) - { - $aResult[] = \RainLoop\Enumerations\Capa::SIEVE; - } - } - } - - if ($oConfig->Get('security', 'allow_two_factor_auth', false) && - ($bAdmin || ($oAccount && !$oAccount->IsAdditionalAccount()))) - { - $aResult[] = \RainLoop\Enumerations\Capa::TWO_FACTOR; - - if ($oConfig->Get('security', 'force_two_factor_auth', false) && - ($bAdmin || ($oAccount && !$oAccount->IsAdditionalAccount()))) - { - $aResult[] = \RainLoop\Enumerations\Capa::TWO_FACTOR_FORCE; - } - } - - if ($oConfig->Get('capa', 'help', true) && !$bMobile) - { - $aResult[] = \RainLoop\Enumerations\Capa::HELP; - } - - if ($oConfig->Get('capa', 'attachments_actions', false)) - { - $aResult[] = \RainLoop\Enumerations\Capa::ATTACHMENTS_ACTIONS; - } - - if ($oConfig->Get('capa', 'message_actions', true)) - { - $aResult[] = \RainLoop\Enumerations\Capa::MESSAGE_ACTIONS; - } - - if ($oConfig->Get('capa', 'composer', true)) - { - $aResult[] = \RainLoop\Enumerations\Capa::COMPOSER; - - if ($oConfig->Get('capa', 'contacts', true)) - { - $aResult[] = \RainLoop\Enumerations\Capa::CONTACTS; - } - } - - if ($oConfig->Get('capa', 'search', true)) - { - $aResult[] = \RainLoop\Enumerations\Capa::SEARCH; - - if ($oConfig->Get('capa', 'search_adv', true) && !$bMobile) - { - $aResult[] = \RainLoop\Enumerations\Capa::SEARCH_ADV; - } - } - - if ($oConfig->Get('labs', 'allow_gravatar', false)) - { - $aResult[] = \RainLoop\Enumerations\Capa::GRAVATAR; - } - - if ($oConfig->Get('interface', 'show_attachment_thumbnail', true)) - { - $aResult[] = \RainLoop\Enumerations\Capa::ATTACHMENT_THUMBNAILS; - } - - if ($oConfig->Get('labs', 'allow_prefetch', false) && !$bMobile) - { - $aResult[] = \RainLoop\Enumerations\Capa::PREFETCH; - } - - if (!\RainLoop\Utils::IsOwnCloud()) - { - $aResult[] = \RainLoop\Enumerations\Capa::AUTOLOGOUT; - } - - return $aResult; - } - - /** - * @param bool $bAdmin - * @param bool $bMobile - * @param string $sName - * @param \RainLoop\Model\Account $oAccount = null - * - * @return bool - */ - public function GetCapa($bAdmin, $bMobile, $sName, $oAccount = null) - { - return \in_array($sName, $this->Capa($bAdmin, $bMobile, $oAccount)); - } - - /** - * @param string $sKey - * - * @return string - */ - public function etag($sKey) - { - return \md5('Etag:'.\md5($sKey.\md5($this->Config()->Get('cache', 'index', '')))); - } - - /** - * @param string $sKey - * @param bool $bForce = false - * - * @return bool - */ - public function cacheByKey($sKey, $bForce = false) - { - $bResult = false; - if (!empty($sKey) && ($bForce || ($this->Config()->Get('cache', 'enable', true) && $this->Config()->Get('cache', 'http', true)))) - { - $iExpires = $this->Config()->Get('cache', 'http_expires', 3600); - if (0 < $iExpires) - { - $this->oHttp->ServerUseCache($this->etag($sKey), 1382478804, time() + $iExpires); - $bResult = true; - } - } - - if (!$bResult) - { - $this->oHttp->ServerNoCache(); - } - - return $bResult; - } - - /** - * @param string $sKey - * @param bool $bForce = false - * - * @return void - */ - public function verifyCacheByKey($sKey, $bForce = false) - { - if (!empty($sKey) && ($bForce || $this->Config()->Get('cache', 'enable', true) && $this->Config()->Get('cache', 'http', true))) - { - $sIfNoneMatch = $this->Http()->GetHeader('If-None-Match', ''); - if ($this->etag($sKey) === $sIfNoneMatch) - { - $this->Http()->StatusHeader(304); - $this->cacheByKey($sKey); - exit(0); - } - } - } - - /** - * @param \RainLoop\Model\Account $oAccount - * @param string $sHash - * - * @return array - */ - private function getMimeFileByHash($oAccount, $sHash) - { - $aValues = $this->getDecodedRawKeyValue($sHash); - - $sFolder = isset($aValues['Folder']) ? $aValues['Folder'] : ''; - $iUid = (int) isset($aValues['Uid']) ? $aValues['Uid'] : 0; - $sMimeIndex = (string) isset($aValues['MimeIndex']) ? $aValues['MimeIndex'] : ''; - - $sContentTypeIn = (string) isset($aValues['MimeType']) ? $aValues['MimeType'] : ''; - $sFileNameIn = (string) isset($aValues['FileName']) ? $aValues['FileName'] : ''; - - $oFileProvider = $this->FilesProvider(); - - $sResultHash = ''; - - $mResult = $this->MailClient()->MessageMimeStream(function($rResource, $sContentType, $sFileName, $sMimeIndex = '') - use ($oAccount, $oFileProvider, $sFileNameIn, $sContentTypeIn, &$sResultHash) { - - unset($sContentType, $sFileName, $sMimeIndex); - - if ($oAccount && \is_resource($rResource)) - { - $sHash = \MailSo\Base\Utils::Md5Rand($sFileNameIn.'~'.$sContentTypeIn); - $rTempResource = $oFileProvider->GetFile($oAccount, $sHash, 'wb+'); - - if (@\is_resource($rTempResource)) - { - if (false !== \MailSo\Base\Utils::MultipleStreamWriter($rResource, array($rTempResource))) - { - $sResultHash = $sHash; - } - - @\fclose($rTempResource); - } - } - - }, $sFolder, $iUid, true, $sMimeIndex); - - $aValues['FileHash'] = ''; - if ($mResult) - { - $aValues['FileHash'] = $sResultHash; - } - - return $aValues; - } - - /** - * @param \Imagine\Image\AbstractImage $oImage - * @param int $iOrientation - */ - private function rotateImageByOrientation(&$oImage, $iOrientation) - { - if (0 < $iOrientation) - { - switch ($iOrientation) - { - default: - case 1: - break; - - case 2: // flip horizontal - $oImage->flipHorizontally(); - break; - - case 3: // rotate 180 - $oImage->rotate(180); - break; - - case 4: // flip vertical - $oImage->flipVertically(); - break; - - case 5: // vertical flip + 90 rotate - $oImage->flipVertically(); - $oImage->rotate(90); - break; - - case 6: // rotate 90 - $oImage->rotate(90); - break; - - case 7: // horizontal flip + 90 rotate - $oImage->flipHorizontally(); - $oImage->rotate(90); - break; - - case 8: // rotate 270 - $oImage->rotate(270); - break; - } - } - } - - /** - * @param \Imagine\Image\AbstractImage $oImage - */ - public function correctImageOrientation($oImage, $bDetectImageOrientation = true, $iThumbnailBoxSize = null) - { - $iOrientation = 1; - if ($bDetectImageOrientation && \MailSo\Base\Utils::FunctionExistsAndEnabled('exif_read_data') && - \MailSo\Base\Utils::FunctionExistsAndEnabled('gd_info')) - { - $oMetadata = $oImage->metadata(new \Imagine\Image\Metadata\ExifMetadataReader()); - $iOrientation = isset($oMetadata['ifd0.Orientation']) && - is_numeric($oMetadata['ifd0.Orientation']) ? (int) $oMetadata['ifd0.Orientation'] : 1; - } - - if ($iThumbnailBoxSize && 0 < $iThumbnailBoxSize) - { - $oImage = $oImage->thumbnail( - new \Imagine\Image\Box($iThumbnailBoxSize, $iThumbnailBoxSize), - \Imagine\Image\ImageInterface::THUMBNAIL_OUTBOUND); - - $this->rotateImageByOrientation($oImage, $iOrientation); - } - else - { - $this->rotateImageByOrientation($oImage, $iOrientation); - } - - return $oImage; - } - - /** - * @param bool $bDownload - * @param bool $bThumbnail = false - * - * @return bool - */ - private function rawSmart($bDownload, $bThumbnail = false) - { - $sRawKey = (string) $this->GetActionParam('RawKey', ''); - $aValues = $this->getDecodedRawKeyValue($sRawKey); - - $sRange = $this->Http()->GetHeader('Range'); - - $aMatch = array(); - $sRangeStart = $sRangeEnd = ''; - $bIsRangeRequest = false; - - if (!empty($sRange) && 'bytes=0-' !== \strtolower($sRange) && \preg_match('/^bytes=([0-9]+)-([0-9]*)/i', \trim($sRange), $aMatch)) - { - $sRangeStart = $aMatch[1]; - $sRangeEnd = $aMatch[2]; - - $bIsRangeRequest = true; - } - - $sFolder = isset($aValues['Folder']) ? $aValues['Folder'] : ''; - $iUid = isset($aValues['Uid']) ? (int) $aValues['Uid'] : 0; - $sMimeIndex = isset($aValues['MimeIndex']) ? (string) $aValues['MimeIndex'] : ''; - - $sContentTypeIn = isset($aValues['MimeType']) ? (string) $aValues['MimeType'] : ''; - $sFileNameIn = isset($aValues['FileName']) ? (string) $aValues['FileName'] : ''; - $sFileHashIn = isset($aValues['FileHash']) ? (string) $aValues['FileHash'] : ''; - - $bDetectImageOrientation = !!$this->Config()->Get('labs', 'detect_image_exif_orientation', true); - - if (!empty($sFileHashIn)) - { - $this->verifyCacheByKey($sRawKey); - - $oAccount = $this->getAccountFromToken(); - - $sContentTypeOut = empty($sContentTypeIn) ? - \MailSo\Base\Utils::MimeContentType($sFileNameIn) : $sContentTypeIn; - - $sFileNameOut = $this->MainClearFileName($sFileNameIn, $sContentTypeIn, $sMimeIndex); - - $rResource = $this->FilesProvider()->GetFile($oAccount, $sFileHashIn); - if (\is_resource($rResource)) - { - $sFileNameOut = \MailSo\Base\Utils::ConvertEncoding( - $sFileNameOut, \MailSo\Base\Enumerations\Charset::UTF_8, - \MailSo\Base\Enumerations\Charset::CP858); - - \header('Content-Type: '.$sContentTypeOut); - \header('Content-Disposition: attachment; '. - \trim(\MailSo\Base\Utils::EncodeHeaderUtf8AttributeValue('filename', $sFileNameOut)), true); - - \header('Accept-Ranges: none', true); - \header('Content-Transfer-Encoding: binary'); - - \MailSo\Base\Utils::FpassthruWithTimeLimitReset($rResource); - return true; - } - - return false; - } - else - { - if (!empty($sFolder) && 0 < $iUid) - { - $this->verifyCacheByKey($sRawKey); - } - } - - $oAccount = $this->initMailClientConnection(); - - $self = $this; - return $this->MailClient()->MessageMimeStream( - function($rResource, $sContentType, $sFileName, $sMimeIndex = '') use ( - $self, $oAccount, $sRawKey, $sContentTypeIn, $sFileNameIn, $bDownload, $bThumbnail, $bDetectImageOrientation, - $bIsRangeRequest, $sRangeStart, $sRangeEnd - ) { - if ($oAccount && \is_resource($rResource)) - { - \MailSo\Base\Utils::ResetTimeLimit(); - - $sContentTypeOut = $sContentTypeIn; - if (empty($sContentTypeOut)) - { - $sContentTypeOut = $sContentType; - if (empty($sContentTypeOut)) - { - $sContentTypeOut = (empty($sFileName)) ? 'text/plain' : \MailSo\Base\Utils::MimeContentType($sFileName); - } - } - - $sFileNameOut = $sFileNameIn; - if (empty($sFileNameOut)) - { - $sFileNameOut = $sFileName; - } - - $sFileNameOut = $self->MainClearFileName($sFileNameOut, $sContentTypeOut, $sMimeIndex); - - $self->cacheByKey($sRawKey); - - $sLoadedData = null; - if (!$bDownload) - { - if ($bThumbnail) - { - try - { - $oImagine = new \Imagine\Gd\Imagine(); - - $oImage = $oImagine->load(\stream_get_contents($rResource)); - - $oImage = $self->correctImageOrientation($oImage, $bDetectImageOrientation, 60); - - \header('Content-Disposition: inline; '. - \trim(\MailSo\Base\Utils::EncodeHeaderUtf8AttributeValue('filename', $sFileNameOut.'_thumb60x60.png')), true); - - $oImage->show('png'); - } - catch (\Exception $oException) - { - $self->Logger()->WriteExceptionShort($oException); - } - } - else if ($bDetectImageOrientation && - \in_array($sContentTypeOut, array('image/png', 'image/jpeg', 'image/jpg')) && - \MailSo\Base\Utils::FunctionExistsAndEnabled('gd_info')) - { - try - { - $oImagine = new \Imagine\Gd\Imagine(); - - $sLoadedData = \stream_get_contents($rResource); - - $oImage = $oImagine->load($sLoadedData); - - $oImage = $self->correctImageOrientation($oImage, $bDetectImageOrientation); - - \header('Content-Disposition: inline; '. - \trim(\MailSo\Base\Utils::EncodeHeaderUtf8AttributeValue('filename', $sFileNameOut)), true); - - $oImage->show($sContentTypeOut === 'image/png' ? 'png' : 'jpg'); - } - catch (\Exception $oException) - { - $self->Logger()->WriteExceptionShort($oException); - } - } - else - { - $sLoadedData = \stream_get_contents($rResource); - } - } - - if ($bDownload || $sLoadedData) - { - if (!headers_sent()) { - \header('Content-Type: '.$sContentTypeOut); - \header('Content-Disposition: '.($bDownload ? 'attachment' : 'inline').'; '. - \trim(\MailSo\Base\Utils::EncodeHeaderUtf8AttributeValue('filename', $sFileNameOut)), true); - - \header('Accept-Ranges: bytes'); - \header('Content-Transfer-Encoding: binary'); - } - - if ($bIsRangeRequest && !$sLoadedData) - { - $sLoadedData = \stream_get_contents($rResource); - } - - \MailSo\Base\Utils::ResetTimeLimit(); - - if ($sLoadedData) - { - if ($bIsRangeRequest && (0 < \strlen($sRangeStart) || 0 < \strlen($sRangeEnd))) - { - $iFullContentLength = \strlen($sLoadedData); - - $self->Http()->StatusHeader(206); - - $iRangeStart = (int) $sRangeStart; - $iRangeEnd = (int) $sRangeEnd; - - if ('' === $sRangeEnd) - { - $sLoadedData = 0 < $iRangeStart ? \substr($sLoadedData, $iRangeStart) : $sLoadedData; - } - else - { - if ($iRangeStart < $iRangeEnd) - { - $sLoadedData = \substr($sLoadedData, $iRangeStart, $iRangeEnd - $iRangeStart); - } - else - { - $sLoadedData = 0 < $iRangeStart ? \substr($sLoadedData, $iRangeStart) : $sLoadedData; - } - } - - $iContentLength = \strlen($sLoadedData); - - if (0 < $iContentLength) - { - \header('Content-Length: '.$iContentLength, true); - \header('Content-Range: bytes '.$sRangeStart.'-'.(0 < $iRangeEnd ? $iRangeEnd : $iFullContentLength - 1).'/'.$iFullContentLength); - } - - echo $sLoadedData; - } - else - { - echo $sLoadedData; - } - - unset($sLoadedData); - } - else - { - \MailSo\Base\Utils::FpassthruWithTimeLimitReset($rResource); - } - } - } - }, $sFolder, $iUid, true, $sMimeIndex); - } - - /** - * @return bool - */ - public function RawDownload() - { - return $this->rawSmart(true); - } - - /** - * @return bool - */ - public function RawView() - { - return $this->rawSmart(false); - } - - /** - * @return bool - */ - public function RawViewThumbnail() - { - return $this->rawSmart(false, true); - } - - /** - * @return bool - */ - public function RawUserBackground() - { - $sRawKey = (string) $this->GetActionParam('RawKey', ''); - $this->verifyCacheByKey($sRawKey); - - $oAccount = $this->getAccountFromToken(); - - $sData = $this->StorageProvider()->Get($oAccount, - \RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG, - 'background' - ); - - if (!empty($sData)) - { - $aData = \json_decode($sData, true); - unset($sData); - - if (!empty($aData['ContentType']) && !empty($aData['Raw']) && - \in_array($aData['ContentType'], array('image/png', 'image/jpg', 'image/jpeg'))) - { - $this->cacheByKey($sRawKey); - - @\header('Content-Type: '.$aData['ContentType']); - echo \base64_decode($aData['Raw']); - unset($aData); - - return true; - } - } - - return false; - } - - /** - * @return bool - */ - public function RawPublic() - { - $sRawKey = (string) $this->GetActionParam('RawKey', ''); - $this->verifyCacheByKey($sRawKey); - - $sHash = $sRawKey; - $sData = ''; - - if (!empty($sHash)) - { - $sData = $this->StorageProvider()->Get(null, - \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, - \RainLoop\KeyPathHelper::PublicFile($sHash) - ); - } - - $aMatch = array(); - if (!empty($sData) && 0 === \strpos($sData, 'data:') && - \preg_match('/^data:([^:]+):/', $sData, $aMatch) && !empty($aMatch[1])) - { - $sContentType = \trim($aMatch[1]); - if (\in_array($sContentType, array('image/png', 'image/jpg', 'image/jpeg'))) - { - $this->cacheByKey($sRawKey); - - @\header('Content-Type: '.$sContentType); - echo \preg_replace('/^data:[^:]+:/', '', $sData); - unset($sData); - - return true; - } - } - - return false; - } - - /** - * @param string $sFileName - * - * @return bool - */ - public function isFileHasFramedPreview($sFileName) - { - $sExt = \MailSo\Base\Utils::GetFileExtension($sFileName); - return \in_array($sExt, array('doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx')); - } - - /** - * @param string $sFileName - * - * @return bool - */ - public function isFileHasThumbnail($sFileName) - { - static $aCache = array(); - - $sExt = \MailSo\Base\Utils::GetFileExtension($sFileName); - if (isset($aCache[$sExt])) - { - return $aCache[$sExt]; - } - - $bResult = \function_exists('gd_info'); - if ($bResult) - { - $bResult = false; - switch ($sExt) - { - case 'png': - $bResult = \function_exists('imagecreatefrompng'); - break; - case 'gif': - $bResult = \function_exists('imagecreatefromgif'); - break; - case 'jpg': - case 'jpeg': - $bResult = \function_exists('imagecreatefromjpeg'); - break; - } - } - - $aCache[$sExt] = $bResult; - - return $bResult; - } - - /** - * @return bool - */ - public function RawAvatar() - { - $sData = ''; - - $sRawKey = (string) $this->GetActionParam('RawKey', ''); - $sRawKey = \urldecode($sRawKey); - - $this->verifyCacheByKey($sRawKey); - - if (0 < \strlen($sRawKey) && \preg_match('/^[^@]+@([^@]+)$/', $sRawKey)) - { - $sEmail = \MailSo\Base\Utils::IdnToAscii($sRawKey, true); - - $iCode = 0; - $sContentType = ''; - - $sGravatarUrl = 'http://gravatar.com/avatar/'.\md5(strtolower($sEmail)).'.jpg?s=80&d=404'; - - $this->Logger()->Write('gravatar: '.$sGravatarUrl); - - $sData = $this->Http()->GetUrlAsString($sGravatarUrl, null, $sContentType, $iCode, null, 5, - $this->Config()->Get('labs', 'curl_proxy', ''), $this->Config()->Get('labs', 'curl_proxy_auth', '')); - - $sContentType = \strtolower(\trim($sContentType)); - if (200 !== $iCode || empty($sData) || !\in_array($sContentType, array('image/jpeg', 'image/jpg', 'image/png'))) - { - $this->Logger()->Write('gravatar: code: '.$iCode.', content-type: '.$sContentType); - - $sData = ''; - - $aMatch = array(); - if (\preg_match('/^[^@]+@([a-z0-9\-\.]+)$/', $sEmail, $aMatch) && !empty($aMatch[1])) - { - $sDomain = $aMatch[1]; - if (\file_exists(APP_VERSION_ROOT_PATH.'app/resources/images/services/'.$sDomain.'.png')) - { - $sContentType = 'image/png'; - $sData = \file_get_contents(APP_VERSION_ROOT_PATH.'app/resources/images/services/'.$sDomain.'.png'); - } - } - } - } - - if (empty($sData) || empty($sContentType)) - { - $sContentType = 'image/png'; - $sData = \file_get_contents(APP_VERSION_ROOT_PATH.'app/resources/images/empty-contact.png'); - } - - $this->cacheByKey($sRawKey); - \header('Content-Type: '.$sContentType); - echo $sData; - return true; - } - - /** - * @return bool - */ - public function RawContactsVcf() - { - $oAccount = $this->getAccountFromToken(); - - \header('Content-Type: text/x-vcard; charset=UTF-8'); - \header('Content-Disposition: attachment; filename="contacts.vcf"', true); - \header('Accept-Ranges: none', true); - \header('Content-Transfer-Encoding: binary'); - - $this->oHttp->ServerNoCache(); - - return $this->AddressBookProvider($oAccount)->IsActive() ? - $this->AddressBookProvider($oAccount)->Export($oAccount->ParentEmailHelper(), 'vcf') : false; - } - - /** - * @return bool - */ - public function RawContactsCsv() - { - $oAccount = $this->getAccountFromToken(); - - \header('Content-Type: text/csv; charset=UTF-8'); - \header('Content-Disposition: attachment; filename="contacts.csv"', true); - \header('Accept-Ranges: none', true); - \header('Content-Transfer-Encoding: binary'); - - $this->oHttp->ServerNoCache(); - - return $this->AddressBookProvider($oAccount)->IsActive() ? - $this->AddressBookProvider($oAccount)->Export($oAccount->ParentEmailHelper(), 'csv') : false; - } - - /** - * @return \RainLoop\Model\Account|bool - */ - private function initMailClientConnection() - { - $oAccount = null; - - if (!$this->MailClient()->IsLoggined()) - { - $oAccount = $this->getAccountFromToken(); - - try - { - $oAccount->IncConnectAndLoginHelper($this->Plugins(), $this->MailClient(), $this->Config()); - } - catch (\MailSo\Net\Exceptions\ConnectionException $oException) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::ConnectionError, $oException); - } - catch (\Exception $oException) - { - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::AuthError, $oException); - } - - $this->MailClient()->ImapClient()->__FORCE_SELECT_ON_EXAMINE__ = !!$this->Config()->Get('labs', 'use_imap_force_selection'); - } - - return $oAccount; - } - - /** - * @param string $sRawKey - * - * @return array | false - */ - private function getDecodedRawKeyValue($sRawKey) - { - $bResult = false; - if (!empty($sRawKey)) - { - $aValues = \RainLoop\Utils::DecodeKeyValuesQ($sRawKey); - if (is_array($aValues)) - { - $bResult = $aValues; - } - } - - return $bResult; - } - - /** - * @param string $sRawKey - * @param int | null $iLenCache - * @return array | bool - */ - private function getDecodedClientRawKeyValue($sRawKey, $iLenCache = null) - { - $mResult = false; - if (!empty($sRawKey)) - { - $sRawKey = \MailSo\Base\Utils::UrlSafeBase64Decode($sRawKey); - $aValues = explode("\x0", $sRawKey); - - if (is_array($aValues) && (null === $iLenCache || $iLenCache === count($aValues))) - { - $mResult = $aValues; - } - } - - return $mResult; - } - - /** - * @return string - */ - public function StaticCache() - { - static $sCache = null; - if (!$sCache) - { - $sCache = \md5(APP_VERSION.$this->Plugins()->Hash()); - } - return $sCache; - } - - /** - * @param string $sTheme - * - * @return string - */ - public function ThemeLink($sTheme, $bAdmin) - { - return './?/Css/0/'.($bAdmin ? 'Admin' : 'User').'/-/'.$sTheme.'/-/'.$this->StaticCache().'/Hash/-/'; - } - - /** - * @param string $sTheme - * - * @return string - */ - public function ValidateTheme($sTheme, $bMobile = false) - { - if ($bMobile) - { - return 'Mobile'; - } - - return \in_array($sTheme, $this->GetThemes($bMobile)) ? - $sTheme : $this->Config()->Get('themes', 'default', $bMobile ? 'Mobile' : 'Default'); - } - - /** - * @param string $sLanguage - * @param string $sDefault = '' - * @param bool $bAdmin = false - * @param bool $bAllowEmptyResult = false - * - * @return string - */ - public function ValidateLanguage($sLanguage, $sDefault = '', $bAdmin = false, $bAllowEmptyResult = false) - { - $sResult = ''; - $aLang = $this->GetLanguages($bAdmin); - - if (\is_array($aLang)) - { - $aHelper = array('en' => 'en_us', 'ar' => 'ar_sa', 'cs' => 'cs_cz', 'no' => 'nb_no', 'ua' => 'uk_ua', - 'cn' => 'zh_cn', 'zh' => 'zh_cn', 'tw' => 'zh_tw', 'fa' => 'fa_ir'); - - $sLanguage = isset($aHelper[$sLanguage]) ? $aHelper[$sLanguage] : $sLanguage; - $sDefault = isset($aHelper[$sDefault]) ? $aHelper[$sDefault] : $sDefault; - - $sLanguage = \strtolower(\str_replace('-', '_', $sLanguage)); - if (2 === strlen($sLanguage)) - { - $sLanguage = $sLanguage.'_'.$sLanguage; - } - - $sDefault = \strtolower(\str_replace('-', '_', $sDefault)); - if (2 === strlen($sDefault)) - { - $sDefault = $sDefault.'_'.$sDefault; - } - - $sLanguage = \preg_replace_callback('/_([a-zA-Z0-9]{2})$/', function ($aData) { - return \strtoupper($aData[0]); - }, $sLanguage); - - $sDefault = \preg_replace_callback('/_([a-zA-Z0-9]{2})$/', function ($aData) { - return \strtoupper($aData[0]); - }, $sDefault); - - if (\in_array($sLanguage, $aLang)) - { - $sResult = $sLanguage; - } - - if (empty($sResult) && !empty($sDefault) && \in_array($sDefault, $aLang)) - { - $sResult = $sDefault; - } - - if (empty($sResult) && !$bAllowEmptyResult) - { - $sResult = $this->Config()->Get('webmail', $bAdmin ? 'language_admin' : 'language', 'en_US'); - $sResult = \in_array($sResult, $aLang) ? $sResult : 'en_US'; - } - } - - return $sResult; - } - - /** - * @param string $sType - * - * @return string - */ - public function ValidateContactPdoType($sType) - { - return \in_array($sType, array('mysql', 'pgsql', 'sqlite')) ? $sType : 'sqlite'; - } - - /** - * @staticvar array $aCache - * - * @return array - */ - public function GetThemes($bMobile = false, $bIncludeMobile = true) - { - if ($bMobile) - { - return array('Mobile'); - } - - static $aCache = array('full' => null, 'mobile' => null); - if ($bIncludeMobile && \is_array($aCache['full'])) - { - return $aCache['full']; - } - else if ($bIncludeMobile && \is_array($aCache['mobile'])) - { - return $aCache['mobile']; - } - - $bClear = false; - $bDefault = false; - $sList = array(); - $sDir = APP_VERSION_ROOT_PATH.'themes'; - if (@\is_dir($sDir)) - { - $rDirH = \opendir($sDir); - if ($rDirH) - { - while (($sFile = \readdir($rDirH)) !== false) - { - if ('.' !== $sFile{0} && \is_dir($sDir.'/'.$sFile) && \file_exists($sDir.'/'.$sFile.'/styles.less')) - { - if ('Default' === $sFile) - { - $bDefault = true; - } - else if ('Clear' === $sFile) - { - $bClear = true; - } - else if ($bIncludeMobile || 'Mobile' !== $sFile) - { - $sList[] = $sFile; - } - } - } - @closedir($rDirH); - } - } - - $sDir = APP_INDEX_ROOT_PATH.'themes'; // custom user themes - if (@\is_dir($sDir)) - { - $rDirH = \opendir($sDir); - if ($rDirH) - { - while (($sFile = \readdir($rDirH)) !== false) - { - if ('.' !== $sFile{0} && \is_dir($sDir.'/'.$sFile) && \file_exists($sDir.'/'.$sFile.'/styles.less')) - { - $sList[] = $sFile.'@custom'; - } - } - - @\closedir($rDirH); - } - } - - $sList = \array_unique($sList); - \sort($sList); - - if ($bDefault) - { - \array_unshift($sList, 'Default'); - } - - if ($bClear) - { - \array_push($sList, 'Clear'); - } - - $aCache[$bIncludeMobile ? 'full' : 'mobile'] = $sList; - return $sList; - } - - /** - * @staticvar array $aCache - * @param bool $bAdmin = false - * - * @return array - */ - public function GetLanguages($bAdmin = false) - { - static $aCache = array(); - $sDir = APP_VERSION_ROOT_PATH.'app/localization/'.($bAdmin ? 'admin' : 'webmail').'/'; - - if (isset($aCache[$sDir])) - { - return $aCache[$sDir]; - } - - $aTop = array(); - $aList = array(); - - if (@\is_dir($sDir)) - { - $rDirH = \opendir($sDir); - if ($rDirH) - { - while (($sFile = \readdir($rDirH)) !== false) - { - if ('.' !== $sFile{0} && \is_file($sDir.'/'.$sFile) && '.yml' === \substr($sFile, -4)) - { - $sLang = \substr($sFile, 0, -4); - if (0 < \strlen($sLang) && 'always' !== $sLang && '_source.en' !== $sLang) - { - \array_push($aList, $sLang); - } - } - } - - @\closedir($rDirH); - } - } - - \sort($aTop); - \sort($aList); - - $aCache[$sDir] = \array_merge($aTop, $aList); - return $aCache[$sDir]; - } - - /** - * @param string $sName - * @param string $sHtml - * - * @return string - */ - public function ProcessTemplate($sName, $sHtml) - { - $sHtml = $this->Plugins()->ProcessTemplate($sName, $sHtml); - $sHtml = \preg_replace('/\{\{INCLUDE\/([a-zA-Z]+)\/PLACE\}\}/', '', $sHtml); - - $sHtml = \preg_replace('/'; - } - - unset($aTemplates); - - return $bJsOutput ? 'window.rainloopTEMPLATES='.\MailSo\Base\Utils::Php2js(array($sHtml), $this->Logger()).';' : $sHtml; - } - - /** - * @param string $sLanguage - * - * @return string - */ - private function convertLanguageNameToMomentLanguageName($sLanguage) - { - $aHelper = array('en_gb' => 'en-gb', 'fr_ca' => 'fr-ca', 'pt_br' => 'pt-br', - 'uk_ua' => 'ua', 'zh_cn' => 'zh-cn', 'zh_tw' => 'zh-tw', 'fa_ir' => 'fa'); - - return isset($aHelper[$sLanguage]) ? $aHelper[$sLanguage] : \substr($sLanguage, 0, 2); - } - - /** - * @param string $sLanguage - * @param bool $bAdmin = false - * @param bool $bWrapByScriptTag = true - * - * @return string - */ - private function compileLanguage($sLanguage, $bAdmin = false, $bWrapByScriptTag = true) - { - $aResultLang = array(); - - $sMoment = 'window.moment && window.moment.locale && window.moment.locale(\'en\');'; - $sMomentFileName = APP_VERSION_ROOT_PATH.'app/localization/moment/'. - $this->convertLanguageNameToMomentLanguageName($sLanguage).'.js'; - - if (\file_exists($sMomentFileName)) - { - $sMoment = \file_get_contents($sMomentFileName); - $sMoment = \preg_replace('/\/\/[^\n]+\n/', '', $sMoment); - } - - \RainLoop\Utils::ReadAndAddLang(APP_VERSION_ROOT_PATH.'app/localization/langs.yml', $aResultLang); - \RainLoop\Utils::ReadAndAddLang(APP_VERSION_ROOT_PATH.'app/localization/'. - ($bAdmin ? 'admin' : 'webmail').'/_source.en.yml', $aResultLang); - \RainLoop\Utils::ReadAndAddLang(APP_VERSION_ROOT_PATH.'app/localization/'. - ($bAdmin ? 'admin' : 'webmail').'/'.$sLanguage.'.yml', $aResultLang); - - $this->Plugins()->ReadLang($sLanguage, $aResultLang); - - $sLangJs = ''; - $aLangKeys = \array_keys($aResultLang); - foreach ($aLangKeys as $sKey) - { - $sString = isset($aResultLang[$sKey]) ? $aResultLang[$sKey] : $sKey; - if (\is_array($sString)) - { - $sString = \implode("\n", $sString); - } - - $sLangJs .= '"'.\str_replace('"', '\\"', \str_replace('\\', '\\\\', $sKey)).'":' - .'"'.\str_replace(array("\r", "\n", "\t"), array('\r', '\n', '\t'), - \str_replace('"', '\\"', \str_replace('\\', '\\\\', $sString))).'",'; - } - - $sResult = empty($sLangJs) ? 'null' : '{'.\substr($sLangJs, 0, -1).'}'; - - return - ($bWrapByScriptTag ? '' : '') - ; - } - - /** - * @param array $aAppData - * @param bool $bWrapByScriptTag = true - * - * @return string - */ - private function compileAppData($aAppData, $bWrapByScriptTag = true) - { - return - ($bWrapByScriptTag ? '' : '') - ; - } -} +oHttp = $oHttp; + $this->oActions = $oActions; + $this->aPaths = array(); + $this->sQuery = ''; + } + + /** + * @return \MailSo\Log\Logger + */ + public function Logger() + { + return $this->oActions->Logger(); + } + + /** + * @return \RainLoop\Plugins\Manager + */ + public function Plugins() + { + return $this->oActions->Plugins(); + } + + /** + * @return \RainLoop\Application + */ + public function Config() + { + return $this->oActions->Config(); + } + + /** + * @return \MailSo\Cache\CacheClient + */ + public function Cacher() + { + return $this->oActions->Cacher(); + } + + /** + * @return \RainLoop\Providers\Storage + */ + public function StorageProvider() + { + return $this->oActions->StorageProvider(); + } + + /** + * @return \RainLoop\Providers\Settings + */ + public function SettingsProvider() + { + return $this->oActions->SettingsProvider(); + } + + /** + * @param array $aPaths + * + * @return \RainLoop\ServiceActions + */ + public function SetPaths($aPaths) + { + $this->aPaths = \is_array($aPaths) ? $aPaths : array(); + return $this; + } + + /** + * @param string $sQuery + * + * @return \RainLoop\ServiceActions + */ + public function SetQuery($sQuery) + { + $this->sQuery = $sQuery; + return $this; + } + + /** + * @return string + */ + public function ServiceAjax() + { + @\ob_start(); + + $aResponseItem = null; + $oException = null; + + $sAction = $this->oHttp->GetPost('Action', null); + if (empty($sAction) && $this->oHttp->IsGet() && !empty($this->aPaths[2])) + { + $sAction = $this->aPaths[2]; + } + + try + { + if ($this->oHttp->IsPost() && !in_array($sAction, array('JsInfo', 'JsError')) && + $this->Config()->Get('security', 'csrf_protection', false) && + $this->oHttp->GetPost('XToken', '') !== \RainLoop\Utils::GetCsrfToken()) + { + throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::InvalidToken); + } + else if (!empty($sAction)) + { + $sMethodName = 'Do'.$sAction; + + $this->Logger()->Write('Action: '.$sMethodName, \MailSo\Log\Enumerations\Type::NOTE, 'AJAX'); + + $aPost = $this->oHttp->GetPostAsArray(); + if (\is_array($aPost) && 0 < \count($aPost)) + { + $this->oActions->SetActionParams($aPost, $sMethodName); + switch ($sMethodName) + { + case 'DoLogin': + case 'DoAdminLogin': + case 'DoAccountAdd': + $this->Logger()->AddSecret($this->oActions->GetActionParam('Password', '')); + break; + case 'DoChangePassword': + $this->Logger()->AddSecret($this->oActions->GetActionParam('PrevPassword', '')); + $this->Logger()->AddSecret($this->oActions->GetActionParam('NewPassword', '')); + break; + } + + $this->Logger()->Write(\MailSo\Base\Utils::Php2js($aPost, $this->Logger()), + \MailSo\Log\Enumerations\Type::INFO, 'POST', true); + } + else if (3 < \count($this->aPaths) && $this->oHttp->IsGet()) + { + $this->oActions->SetActionParams(array( + 'RawKey' => empty($this->aPaths[3]) ? '' : $this->aPaths[3] + ), $sMethodName); + } + + if (\method_exists($this->oActions, $sMethodName) && + \is_callable(array($this->oActions, $sMethodName))) + { + $this->Plugins()->RunHook('ajax.action-pre-call', array($sAction)); + $aResponseItem = \call_user_func(array($this->oActions, $sMethodName)); + $this->Plugins()->RunHook('ajax.action-post-call', array($sAction, &$aResponseItem)); + } + else if ($this->Plugins()->HasAdditionalAjax($sMethodName)) + { + $this->Plugins()->RunHook('ajax.action-pre-call', array($sAction)); + $aResponseItem = $this->Plugins()->RunAdditionalAjax($sMethodName); + $this->Plugins()->RunHook('ajax.action-post-call', array($sAction, &$aResponseItem)); + } + } + + if (!\is_array($aResponseItem)) + { + throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::UnknownError); + } + } + catch (\Exception $oException) + { + $aResponseItem = $this->oActions->ExceptionResponse( + empty($sAction) ? 'Unknown' : $sAction, $oException); + + if (\is_array($aResponseItem) && $oException instanceof \RainLoop\Exceptions\ClientException) + { + if ('Folders' === $sAction) + { + $aResponseItem['ClearAuth'] = true; + } + + if ($oException->getLogoutOnException()) + { + $aResponseItem['Logout'] = true; + if ($oException->getAdditionalMessage()) + { + $this->oActions->SetSpecLogoutCustomMgsWithDeletion($oException->getAdditionalMessage()); + } + } + } + } + + if (\is_array($aResponseItem)) + { + $aResponseItem['Time'] = (int) ((\microtime(true) - APP_START) * 1000); + } + + $this->Plugins()->RunHook('filter.ajax-response', array($sAction, &$aResponseItem)); + + @\header('Content-Type: application/json; charset=utf-8'); + + $sResult = \MailSo\Base\Utils::Php2js($aResponseItem, $this->Logger()); + + $sObResult = @\ob_get_clean(); + + if ($this->Logger()->IsEnabled()) + { + if (0 < \strlen($sObResult)) + { + $this->Logger()->Write($sObResult, \MailSo\Log\Enumerations\Type::ERROR, 'OB-DATA'); + } + + if ($oException) + { + $this->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); + } + + $iLimit = (int) $this->Config()->Get('labs', 'log_ajax_response_write_limit', 0); + $this->Logger()->Write(0 < $iLimit && $iLimit < \strlen($sResult) + ? \substr($sResult, 0, $iLimit).'...' : $sResult, \MailSo\Log\Enumerations\Type::INFO, 'AJAX'); + } + + return $sResult; + } + + /** + * @return string + */ + public function ServiceOwnCloudAuth() + { + $this->oHttp->ServerNoCache(); + + if (!\RainLoop\Utils::IsOwnCloud() || + !isset($_ENV['___rainloop_owncloud_email']) || + !isset($_ENV['___rainloop_owncloud_password']) || + empty($_ENV['___rainloop_owncloud_email']) + ) + { + $this->oActions->SetAuthLogoutToken(); + $this->oActions->Location('./'); + return ''; + } + + $bLogout = true; + + $sEmail = $_ENV['___rainloop_owncloud_email']; + $sPassword = $_ENV['___rainloop_owncloud_password']; + + try + { + $oAccount = $this->oActions->LoginProcess($sEmail, $sPassword); + $this->oActions->AuthToken($oAccount); + + $bLogout = !($oAccount instanceof \RainLoop\Model\Account); + } + catch (\Exception $oException) + { + $this->oActions->Logger()->WriteException($oException); + } + + if ($bLogout) + { + $this->oActions->SetAuthLogoutToken(); + } + + $this->oActions->Location('./'); + return ''; + } + + /** + * @return string + */ + public function ServiceAppend() + { + @\ob_start(); + $bResponse = false; + $oException = null; + try + { + if (\method_exists($this->oActions, 'Append') && + \is_callable(array($this->oActions, 'Append'))) + { + $this->oActions->SetActionParams($this->oHttp->GetPostAsArray(), 'Append'); + $bResponse = \call_user_func(array($this->oActions, 'Append')); + } + } + catch (\Exception $oException) + { + $bResponse = false; + } + + @\header('Content-Type: text/plain; charset=utf-8'); + $sResult = true === $bResponse ? '1' : '0'; + + $sObResult = @\ob_get_clean(); + if (0 < \strlen($sObResult)) + { + $this->Logger()->Write($sObResult, \MailSo\Log\Enumerations\Type::ERROR, 'OB-DATA'); + } + + if ($oException) + { + $this->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); + } + + $this->Logger()->Write($sResult, \MailSo\Log\Enumerations\Type::INFO, 'APPEND'); + + return $sResult; + } + + /** + * @param string $sAction + * @param int $iSizeLimit = 0 + * + * @return string + */ + private function privateUpload($sAction, $iSizeLimit = 0) + { + $oConfig = $this->Config(); + + @\ob_start(); + $aResponseItem = null; + try + { + $aFile = null; + $sInputName = 'uploader'; + $iError = \RainLoop\Enumerations\UploadError::UNKNOWN; + $iSizeLimit = (0 < $iSizeLimit ? $iSizeLimit : ((int) $oConfig->Get('webmail', 'attachment_size_limit', 0))) * 1024 * 1024; + + $iError = UPLOAD_ERR_OK; + $_FILES = isset($_FILES) ? $_FILES : null; + if (isset($_FILES, $_FILES[$sInputName], $_FILES[$sInputName]['name'], $_FILES[$sInputName]['tmp_name'], $_FILES[$sInputName]['size'])) + { + $iError = (isset($_FILES[$sInputName]['error'])) ? (int) $_FILES[$sInputName]['error'] : UPLOAD_ERR_OK; + + if (UPLOAD_ERR_OK === $iError && 0 < $iSizeLimit && $iSizeLimit < (int) $_FILES[$sInputName]['size']) + { + $iError = \RainLoop\Enumerations\UploadError::CONFIG_SIZE; + } + + if (UPLOAD_ERR_OK === $iError) + { + $aFile = $_FILES[$sInputName]; + } + } + else if (!isset($_FILES) || !is_array($_FILES) || 0 === count($_FILES)) + { + $iError = UPLOAD_ERR_INI_SIZE; + } + else + { + $iError = \RainLoop\Enumerations\UploadError::EMPTY_FILES_DATA; + } + + if (\method_exists($this->oActions, $sAction) && + \is_callable(array($this->oActions, $sAction))) + { + $aActionParams = $this->oHttp->GetQueryAsArray(); + + $aActionParams['File'] = $aFile; + $aActionParams['Error'] = $iError; + + $this->oActions->SetActionParams($aActionParams, $sAction); + + $aResponseItem = \call_user_func(array($this->oActions, $sAction)); + } + + if (!is_array($aResponseItem)) + { + throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::UnknownError); + } + } + catch (\Exception $oException) + { + $aResponseItem = $this->oActions->ExceptionResponse($sAction, $oException); + } + + if ('iframe' === $this->oHttp->GetPost('jua-post-type', '')) + { + @\header('Content-Type: text/html; charset=utf-8'); + } + else + { + @\header('Content-Type: application/json; charset=utf-8'); + } + + $this->Plugins()->RunHook('filter.upload-response', array(&$aResponseItem)); + $sResult = \MailSo\Base\Utils::Php2js($aResponseItem, $this->Logger()); + + $sObResult = @\ob_get_clean(); + if (0 < \strlen($sObResult)) + { + $this->Logger()->Write($sObResult, \MailSo\Log\Enumerations\Type::ERROR, 'OB-DATA'); + } + + $this->Logger()->Write($sResult, \MailSo\Log\Enumerations\Type::INFO, 'UPLOAD'); + + return $sResult; + } + + /** + * @return string + */ + public function ServiceUpload() + { + return $this->privateUpload('Upload'); + } + + /** + * @return string + */ + public function ServiceUploadContacts() + { + return $this->privateUpload('UploadContacts', 5); + } + + /** + * @return string + */ + public function ServiceUploadBackground() + { + return $this->privateUpload('UploadBackground', 1); + } + + /** + * @return string + */ + public function ServiceProxyExternal() + { + $bResult = false; + $sData = empty($this->aPaths[1]) ? '' : $this->aPaths[1]; + if (!empty($sData) && $this->oActions->Config()->Get('labs', 'use_local_proxy_for_external_images', false)) + { + $this->oActions->verifyCacheByKey($sData); + + $aData = \RainLoop\Utils::DecodeKeyValuesQ($sData); + if (\is_array($aData) && !empty($aData['Token']) && !empty($aData['Url']) && $aData['Token'] === \RainLoop\Utils::GetConnectionToken()) + { + $iCode = 404; + $sContentType = ''; + $mResult = $this->oHttp->GetUrlAsString($aData['Url'], 'RainLoop External Proxy', $sContentType, $iCode); + + if (false !== $mResult && 200 === $iCode && + \in_array($sContentType, array('image/png', 'image/jpeg', 'image/jpg', 'image/bmp', 'image/gif'))) + { + $bResult = true; + + $this->oActions->cacheByKey($sData); + + \header('Content-Type: '.$sContentType); + echo $mResult; + } + } + } + + if (!$bResult) + { + $this->oHttp->StatusHeader(404); + } + + return ''; + } + + /** + * @return string + */ + public function ServiceRaw() + { + $sResult = ''; + $sRawError = ''; + $sAction = empty($this->aPaths[2]) ? '' : $this->aPaths[2]; + $oException = null; + + try + { + $sRawError = 'Invalid action'; + if (0 !== \strlen($sAction)) + { + $sMethodName = 'Raw'.$sAction; + if (\method_exists($this->oActions, $sMethodName)) + { + @\header('X-Raw-Action: '.$sMethodName, true); + + $sRawError = ''; + $this->oActions->SetActionParams(array( + 'RawKey' => empty($this->aPaths[3]) ? '' : $this->aPaths[3], + 'Params' => $this->aPaths + ), $sMethodName); + + if (!\call_user_func(array($this->oActions, $sMethodName))) + { + $sRawError = 'False result'; + } + else + { + $sRawError = ''; + } + } + else + { + $sRawError = 'Unknown action "'.$sAction.'"'; + } + } + else + { + $sRawError = 'Empty action'; + } + } + catch (\RainLoop\Exceptions\ClientException $oException) + { + $sRawError = 'Exception as result'; + switch ($oException->getCode()) + { + case \RainLoop\Notifications::AuthError: + $sRawError = 'Authentication failed'; + break; + } + } + catch (\Exception $oException) + { + $sRawError = 'Exception as result'; + } + + if (0 < \strlen($sRawError)) + { + $this->oActions->Logger()->Write($sRawError, \MailSo\Log\Enumerations\Type::ERROR); + $this->oActions->Logger()->WriteDump($this->aPaths, \MailSo\Log\Enumerations\Type::ERROR, 'PATHS'); + } + + if ($oException) + { + $this->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR, 'RAW'); + } + + return $sResult; + } + + /** + * @return string + */ + public function ServiceLang() + { +// sleep(2); + $sResult = ''; + @\header('Content-Type: application/javascript; charset=utf-8'); + + if (!empty($this->aPaths[3])) + { + $bAdmim = 'Admin' === (isset($this->aPaths[2]) ? (string) $this->aPaths[2] : 'App'); + $sLanguage = $this->oActions->ValidateLanguage($this->aPaths[3], '', $bAdmim); + + $bCacheEnabled = $this->Config()->Get('labs', 'cache_system_data', true); + if (!empty($sLanguage) && $bCacheEnabled) + { + $this->oActions->verifyCacheByKey($this->sQuery); + } + + $sCacheFileName = ''; + if ($bCacheEnabled) + { + $sCacheFileName = \RainLoop\KeyPathHelper::LangCache( + $sLanguage, $bAdmim, $this->oActions->Plugins()->Hash()); + + $sResult = $this->Cacher()->Get($sCacheFileName); + } + + if (0 === \strlen($sResult)) + { + $sResult = $this->compileLanguage($sLanguage, $bAdmim, false); + if ($bCacheEnabled && 0 < \strlen($sCacheFileName)) + { + $this->Cacher()->Set($sCacheFileName, $sResult); + } + } + + if ($bCacheEnabled) + { + $this->oActions->cacheByKey($this->sQuery); + } + } + + return $sResult; + } + + /** + * @return string + */ + public function ServiceTemplates() + { + $sResult = ''; + @\header('Content-Type: application/javascript; charset=utf-8'); + + $bCacheEnabled = $this->Config()->Get('labs', 'cache_system_data', true); + if ($bCacheEnabled) + { + $this->oActions->verifyCacheByKey($this->sQuery); + } + + $bAdmin = false !== \strpos($this->sQuery, 'Admin'); + + $sCacheFileName = ''; + if ($bCacheEnabled) + { + $sCacheFileName = \RainLoop\KeyPathHelper::TemplatesCache($bAdmin, $this->oActions->Plugins()->Hash()); + $sResult = $this->Cacher()->Get($sCacheFileName); + } + + if (0 === \strlen($sResult)) + { + $sResult = $this->compileTemplates($bAdmin); + if ($bCacheEnabled && 0 < \strlen($sCacheFileName)) + { + $this->Cacher()->Set($sCacheFileName, $sResult); + } + } + + if ($bCacheEnabled) + { + $this->oActions->cacheByKey($this->sQuery); + } + + return $sResult; + } + + /** + * @return string + */ + public function ServicePlugins() + { + $sResult = ''; + $bAdmin = !empty($this->aPaths[2]) && 'Admin' === $this->aPaths[2]; + + @\header('Content-Type: application/javascript; charset=utf-8'); + + $bCacheEnabled = $this->Config()->Get('labs', 'cache_system_data', true); + if ($bCacheEnabled) + { + $this->oActions->verifyCacheByKey($this->sQuery); + } + + $sCacheFileName = ''; + if ($bCacheEnabled) + { + $sCacheFileName = \RainLoop\KeyPathHelper::PluginsJsCache($this->oActions->Plugins()->Hash()); + $sResult = $this->Cacher()->Get($sCacheFileName); + } + + if (0 === strlen($sResult)) + { + $sResult = $this->Plugins()->CompileJs($bAdmin); + if ($bCacheEnabled && 0 < \strlen($sCacheFileName)) + { + $this->Cacher()->Set($sCacheFileName, $sResult); + } + } + + if ($bCacheEnabled) + { + $this->oActions->cacheByKey($this->sQuery); + } + + return $sResult; + } + + /** + * @return string + */ + public function ServiceCss() + { + $sResult = ''; + + $bAdmin = !empty($this->aPaths[2]) && 'Admin' === $this->aPaths[2]; + $bJson = !empty($this->aPaths[9]) && 'Json' === $this->aPaths[9]; + + if ($bJson) + { + @\header('Content-Type: application/json; charset=utf-8'); + } + else + { + @\header('Content-Type: text/css; charset=utf-8'); + } + + $sTheme = ''; + if (!empty($this->aPaths[4])) + { + $sTheme = $this->oActions->ValidateTheme($this->aPaths[4]); + $sRealTheme = $sTheme; + + $bCustomTheme = '@custom' === \substr($sTheme, -7); + if ($bCustomTheme) + { + $sRealTheme = \substr($sTheme, 0, -7); + } + + $bCacheEnabled = $this->Config()->Get('labs', 'cache_system_data', true); + if ($bCacheEnabled) + { + $this->oActions->verifyCacheByKey($this->sQuery); + } + + $sCacheFileName = ''; + if ($bCacheEnabled) + { + $sCacheFileName = \RainLoop\KeyPathHelper::CssCache($sTheme, $this->oActions->Plugins()->Hash()); + $sResult = $this->Cacher()->Get($sCacheFileName); + } + + if (0 === \strlen($sResult)) + { + try + { + include_once APP_VERSION_ROOT_PATH.'app/libraries/lessphp/ctype.php'; + include_once APP_VERSION_ROOT_PATH.'app/libraries/lessphp/lessc.inc.php'; + + $oLess = new \RainLoopVendor\lessc(); + $oLess->setFormatter('compressed'); + + $aResult = array(); + + $sThemeFile = ($bCustomTheme ? APP_INDEX_ROOT_PATH : APP_VERSION_ROOT_PATH).'themes/'.$sRealTheme.'/styles.less'; + $sThemeExtFile = ($bCustomTheme ? APP_INDEX_ROOT_PATH : APP_VERSION_ROOT_PATH).'themes/'.$sRealTheme.'/ext.less'; + + $sThemeValuesFile = APP_VERSION_ROOT_PATH.'app/templates/Themes/values.less'; + $sThemeTemplateFile = APP_VERSION_ROOT_PATH.'app/templates/Themes/template.less'; + + if (\file_exists($sThemeFile) && \file_exists($sThemeTemplateFile) && \file_exists($sThemeValuesFile)) + { + $aResult[] = '@base: "'. + ($bCustomTheme ? \RainLoop\Utils::WebPath() : \RainLoop\Utils::WebVersionPath()). + 'themes/'.$sRealTheme.'/";'; + + $aResult[] = \file_get_contents($sThemeValuesFile); + $aResult[] = \file_get_contents($sThemeFile); + $aResult[] = \file_get_contents($sThemeTemplateFile); + + if (\file_exists($sThemeExtFile)) + { + $aResult[] = \file_get_contents($sThemeExtFile); + } + } + + $aResult[] = $this->Plugins()->CompileCss($bAdmin); + + $sResult = $oLess->compile(\implode("\n", $aResult)); + + if ($bCacheEnabled) + { + if (0 < \strlen($sCacheFileName)) + { + $this->Cacher()->Set($sCacheFileName, $sResult); + } + } + } + catch (\Exception $oException) + { + $this->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR, 'LESS'); + } + } + + if ($bCacheEnabled) + { + $this->oActions->cacheByKey($this->sQuery); + } + } + + return $bJson ? \MailSo\Base\Utils::Php2js(array($sTheme, $sResult), $this->Logger()) : $sResult; + } + + /** + * @return string + */ + public function ServiceSocialGoogle() + { + $bXAuth = '1' === (string) $this->oHttp->GetQuery('xauth', '0'); + return $this->oActions->Social()->GooglePopupService($bXAuth); + } + + /** + * @return string + */ + public function ServiceSocialFacebook() + { + return $this->oActions->Social()->FacebookPopupService(); + } + + /** + * @return string + */ + public function ServiceSocialTwitter() + { + return $this->oActions->Social()->TwitterPopupService(); + } + + /** + * @return string + */ + public function ServiceAppData($sAdd = '') + { + return $this->localAppData(false, $sAdd); + } + + /** + * @return string + */ + public function ServiceAdminAppData($sAdd = '') + { + return $this->localAppData(true, $sAdd); + } + + /** + * @return string + */ + public function ServiceMobileVersion() + { + \RainLoop\Utils::SetCookie(\RainLoop\Actions::RL_MOBILE_TYPE, 'mobile'); + $this->oActions->Location('./'); + return ''; + } + + /** + * @return string + */ + public function ServiceDesktopVersion() + { + \RainLoop\Utils::SetCookie(\RainLoop\Actions::RL_MOBILE_TYPE, 'desktop'); + $this->oActions->Location('./'); + return ''; + } + + /** + * @return string + */ + public function ServiceNoScript() + { + return $this->localError($this->oActions->StaticI18N('STATIC/NO_SCRIPT_TITLE'), $this->oActions->StaticI18N('STATIC/NO_SCRIPT_DESC')); + } + + /** + * @return string + */ + public function ServiceNoCookie() + { + return $this->localError($this->oActions->StaticI18N('STATIC/NO_COOKIE_TITLE'), $this->oActions->StaticI18N('STATIC/NO_COOKIE_DESC')); + } + + /** + * @return string + */ + public function ServiceBadBrowser() + { + $sTitle = $this->oActions->StaticI18N('STATIC/BAD_BROWSER_TITLE'); + $sDesc = \nl2br($this->oActions->StaticI18N('STATIC/BAD_BROWSER_DESC')); + + @\header('Content-Type: text/html; charset=utf-8'); + return \strtr(\file_get_contents(APP_VERSION_ROOT_PATH.'app/templates/BadBrowser.html'), array( + '{{BaseWebStaticPath}}' => \RainLoop\Utils::WebStaticPath(), + '{{ErrorTitle}}' => $sTitle, + '{{ErrorHeader}}' => $sTitle, + '{{ErrorDesc}}' => $sDesc + )); + } + + /** + * @return string + */ + public function ServiceMailto() + { + $this->oHttp->ServerNoCache(); + + $sTo = \trim($this->oHttp->GetQuery('to', '')); + if (!empty($sTo) && \preg_match('/^mailto:/i', $sTo)) + { + $oAccount = $this->oActions->GetAccountFromSignMeToken(); + if ($oAccount) + { + $this->oActions->SetMailtoRequest($sTo); + } + } + + $this->oActions->Location('./'); + return ''; + } + + /** + * @return string + */ + public function ServicePing() + { + $this->oHttp->ServerNoCache(); + + @\header('Content-Type: text/plain; charset=utf-8'); + $this->oActions->Logger()->Write('Pong', \MailSo\Log\Enumerations\Type::INFO, 'PING'); + return 'Pong'; + } + + /** + * @return string + */ + public function ServiceInfo() + { + $this->oHttp->ServerNoCache(); + + if ($this->oActions->IsAdminLoggined(false)) + { + @\header('Content-Type: text/html; charset=utf-8'); + \phpinfo(); + } + } + + /** + * @return string + */ + public function ServiceSso() + { + $this->oHttp->ServerNoCache(); + + $oException = null; + $oAccount = null; + $bLogout = true; + + $sSsoHash = $this->oHttp->GetRequest('hash', ''); + if (!empty($sSsoHash)) + { + $mData = null; + + $sSsoSubData = $this->Cacher()->Get(\RainLoop\KeyPathHelper::SsoCacherKey($sSsoHash)); + if (!empty($sSsoSubData)) + { + $mData = \RainLoop\Utils::DecodeKeyValuesQ($sSsoSubData); + $this->Cacher()->Delete(\RainLoop\KeyPathHelper::SsoCacherKey($sSsoHash)); + + if (\is_array($mData) && !empty($mData['Email']) && isset($mData['Password'], $mData['Time']) && + (0 === $mData['Time'] || \time() - 10 < $mData['Time'])) + { + $sEmail = \trim($mData['Email']); + $sPassword = $mData['Password']; + + $aAdditionalOptions = isset($mData['AdditionalOptions']) && \is_array($mData['AdditionalOptions']) && + 0 < \count($mData['AdditionalOptions']) ? $mData['AdditionalOptions'] : null; + + try + { + $oAccount = $this->oActions->LoginProcess($sEmail, $sPassword); + + if ($oAccount instanceof \RainLoop\Model\Account && $aAdditionalOptions) + { + $bNeedToSettings = false; + + $oSettings = $this->SettingsProvider()->Load($oAccount); + if ($oSettings) + { + $sLanguage = isset($aAdditionalOptions['Language']) ? + $aAdditionalOptions['Language'] : ''; + + if ($sLanguage) + { + $sLanguage = $this->oActions->ValidateLanguage($sLanguage); + if ($sLanguage !== $oSettings->GetConf('Language', '')) + { + $bNeedToSettings = true; + $oSettings->SetConf('Language', $sLanguage); + } + } + } + + if ($bNeedToSettings) + { + $this->SettingsProvider()->Save($oAccount, $oSettings); + } + } + + $this->oActions->AuthToken($oAccount); + + $bLogout = !($oAccount instanceof \RainLoop\Model\Account); + } + catch (\Exception $oException) + { + $this->oActions->Logger()->WriteException($oException); + } + } + } + } + + if ($bLogout) + { + $this->oActions->SetAuthLogoutToken(); + } + + $this->oActions->Location('./'); + return ''; + } + + /** + * @return string + */ + public function ServiceRemoteAutoLogin() + { + $oException = null; + $oAccount = null; + $bLogout = true; + + $sEmail = $this->oHttp->GetEnv('REMOTE_USER', ''); + $sPassword = $this->oHttp->GetEnv('REMOTE_PASSWORD', ''); + + if (0 < \strlen($sEmail) && 0 < \strlen(\trim($sPassword))) + { + try + { + $oAccount = $this->oActions->LoginProcess($sEmail, $sPassword); + $this->oActions->AuthToken($oAccount); + $bLogout = !($oAccount instanceof \RainLoop\Model\Account); + } + catch (\Exception $oException) + { + $this->oActions->Logger()->WriteException($oException); + } + } + + if ($bLogout) + { + $this->oActions->SetAuthLogoutToken(); + } + + $this->oActions->Location('./'); + return ''; + } + + /** + * @return string + */ + public function ServiceExternalLogin() + { + $this->oHttp->ServerNoCache(); + + $oException = null; + $oAccount = null; + $bLogout = true; + + if ($this->oActions->Config()->Get('labs', 'allow_external_login', false)) + { + $sEmail = \trim($this->oHttp->GetRequest('Email', '')); + $sPassword = $this->oHttp->GetRequest('Password', ''); + + try + { + $oAccount = $this->oActions->LoginProcess($sEmail, $sPassword); + $this->oActions->AuthToken($oAccount); + $bLogout = !($oAccount instanceof \RainLoop\Model\Account); + } + catch (\Exception $oException) + { + $this->oActions->Logger()->WriteException($oException); + } + + if ($bLogout) + { + $this->oActions->SetAuthLogoutToken(); + } + } + + switch (\strtolower($this->oHttp->GetRequest('Output', 'Redirect'))) + { + case 'json': + + @\header('Content-Type: application/json; charset=utf-8'); + + $aResult = array( + 'Action' => 'ExternalLogin', + 'Result' => $oAccount instanceof \RainLoop\Model\Account ? true : false, + 'ErrorCode' => 0 + ); + + if (!$aResult['Result']) + { + if ($oException instanceof \RainLoop\Exceptions\ClientException) + { + $aResult['ErrorCode'] = $oException->getCode(); + } + else + { + $aResult['ErrorCode'] = \RainLoop\Notifications::AuthError; + } + } + + return \MailSo\Base\Utils::Php2js($aResult, $this->Logger()); + + case 'redirect': + default: + $this->oActions->Location('./'); + break; + } + + return ''; + } + + /** + * @return string + */ + public function ServiceExternalSso() + { + $this->oHttp->ServerNoCache(); + + $sResult = ''; + $bLogout = true; + $sKey = $this->oActions->Config()->Get('labs', 'external_sso_key', ''); + if ($this->oActions->Config()->Get('labs', 'allow_external_sso', false) && + !empty($sKey) && $sKey === \trim($this->oHttp->GetRequest('SsoKey', ''))) + { + $sEmail = \trim($this->oHttp->GetRequest('Email', '')); + $sPassword = $this->oHttp->GetRequest('Password', ''); + + $sResult = \RainLoop\Api::GetUserSsoHash($sEmail, $sPassword); + $bLogout = 0 === \strlen($sResult); + + switch (\strtolower($this->oHttp->GetRequest('Output', 'Plain'))) + { + case 'plain': + @\header('Content-Type: text/plain'); + break; + + case 'json': + @\header('Content-Type: application/json; charset=utf-8'); + $sResult = \MailSo\Base\Utils::Php2js(array( + 'Action' => 'ExternalSso', + 'Result' => $sResult + ), $this->Logger()); + break; + } + } + + if ($bLogout) + { + $this->oActions->SetAuthLogoutToken(); + } + + return $sResult; + } + + private function changeAction() + { + $this->oHttp->ServerNoCache(); + + $oAccount = $this->oActions->GetAccount(); + + if ($oAccount && $this->oActions->GetCapa(false, false, \RainLoop\Enumerations\Capa::ADDITIONAL_ACCOUNTS, $oAccount)) + { + $oAccountToLogin = null; + $sEmail = empty($this->aPaths[2]) ? '' : \urldecode(\trim($this->aPaths[2])); + if (!empty($sEmail)) + { + $sEmail = \MailSo\Base\Utils::IdnToAscii($sEmail); + + $aAccounts = $this->oActions->GetAccounts($oAccount); + if (isset($aAccounts[$sEmail])) + { + $oAccountToLogin = $this->oActions->GetAccountFromCustomToken($aAccounts[$sEmail], false, false); + } + } + + if ($oAccountToLogin) + { + $this->oActions->AuthToken($oAccountToLogin); + } + } + } + + /** + * @return string + */ + public function ServiceChange() + { + $this->changeAction(); + $this->oActions->Location('./'); + return ''; + } + + /** + * @param string $sTitle + * @param string $sDesc + * + * @return mixed + */ + public function ErrorTemplates($sTitle, $sDesc, $bShowBackLink = true) + { + return strtr(file_get_contents(APP_VERSION_ROOT_PATH.'app/templates/Error.html'), array( + '{{BaseWebStaticPath}}' => \RainLoop\Utils::WebStaticPath(), + '{{ErrorTitle}}' => $sTitle, + '{{ErrorHeader}}' => $sTitle, + '{{ErrorDesc}}' => $sDesc, + '{{BackLinkVisibilityStyle}}' => $bShowBackLink ? 'display:inline-block' : 'display:none', + '{{BackLink}}' => $this->oActions->StaticI18N('STATIC/BACK_LINK'), + '{{BackHref}}' => './' + )); + } + + /** + * @param string $sTitle + * @param string $sDesc + * + * @return string + */ + private function localError($sTitle, $sDesc) + { + @header('Content-Type: text/html; charset=utf-8'); + return $this->ErrorTemplates($sTitle, \nl2br($sDesc)); + } + + /** + * @param bool $bAdmin = true + * @param string $sAdd = '' + * + * @return string + */ + private function localAppData($bAdmin = false, $sAdd = '') + { + @\header('Content-Type: application/javascript; charset=utf-8'); + $this->oHttp->ServerNoCache(); + + $sAuthAccountHash = ''; + if (!$bAdmin && 0 === \strlen($this->oActions->GetSpecAuthLogoutTokenWithDeletion())) + { + $sAuthAccountHash = $this->oActions->GetSpecAuthTokenWithDeletion(); + if (empty($sAuthAccountHash)) + { + $sAuthAccountHash = $this->oActions->GetSpecAuthToken(); + } + + if (empty($sAuthAccountHash)) + { + $oAccount = $this->oActions->GetAccountFromSignMeToken(); + if ($oAccount) + { + try + { + $this->oActions->CheckMailConnection($oAccount); + + $this->oActions->AuthToken($oAccount); + + $sAuthAccountHash = $this->oActions->GetSpecAuthToken(); + } + catch (\Exception $oException) + { + $oException = null; + $this->oActions->ClearSignMeData($oAccount); + } + } + } + + $this->oActions->SetSpecAuthToken($sAuthAccountHash); + } + + $sResult = $this->compileAppData($this->oActions->AppData($bAdmin, + 0 === \strpos($sAdd, 'mobile'), '1' === \substr($sAdd, -1), + $sAuthAccountHash), false); + + $this->Logger()->Write($sResult, \MailSo\Log\Enumerations\Type::INFO, 'APPDATA'); + + return $sResult; + } + + /** + * @param bool $bAdmin = false + * @param bool $bJsOutput = true + * + * @return string + */ + public function compileTemplates($bAdmin = false, $bJsOutput = true) + { + $aTemplates = array(); + + \RainLoop\Utils::CompileTemplates($aTemplates, APP_VERSION_ROOT_PATH.'app/templates/Views/Components', 'Component'); + \RainLoop\Utils::CompileTemplates($aTemplates, APP_VERSION_ROOT_PATH.'app/templates/Views/'.($bAdmin ? 'Admin' : 'User')); + \RainLoop\Utils::CompileTemplates($aTemplates, APP_VERSION_ROOT_PATH.'app/templates/Views/Common'); + + $this->oActions->Plugins()->CompileTemplate($aTemplates, $bAdmin); + + $sHtml = ''; + foreach ($aTemplates as $sName => $sFile) + { + $sName = \preg_replace('/[^a-zA-Z0-9]/', '', $sName); + $sHtml .= ''; + } + + unset($aTemplates); + + return $bJsOutput ? 'window.rainloopTEMPLATES='.\MailSo\Base\Utils::Php2js(array($sHtml), $this->Logger()).';' : $sHtml; + } + + /** + * @param string $sLanguage + * + * @return string + */ + private function convertLanguageNameToMomentLanguageName($sLanguage) + { + $aHelper = array('en_gb' => 'en-gb', 'fr_ca' => 'fr-ca', 'pt_br' => 'pt-br', + 'uk_ua' => 'ua', 'zh_cn' => 'zh-cn', 'zh_tw' => 'zh-tw', 'fa_ir' => 'fa'); + + return isset($aHelper[$sLanguage]) ? $aHelper[$sLanguage] : \substr($sLanguage, 0, 2); + } + + /** + * @param string $sLanguage + * @param bool $bAdmin = false + * @param bool $bWrapByScriptTag = true + * + * @return string + */ + private function compileLanguage($sLanguage, $bAdmin = false, $bWrapByScriptTag = true) + { + $aResultLang = array(); + + $sMoment = 'window.moment && window.moment.locale && window.moment.locale(\'en\');'; + $sMomentFileName = APP_VERSION_ROOT_PATH.'app/localization/moment/'. + $this->convertLanguageNameToMomentLanguageName($sLanguage).'.js'; + + if (\file_exists($sMomentFileName)) + { + $sMoment = \file_get_contents($sMomentFileName); + $sMoment = \preg_replace('/\/\/[^\n]+\n/', '', $sMoment); + } + + \RainLoop\Utils::ReadAndAddLang(APP_VERSION_ROOT_PATH.'app/localization/langs.yml', $aResultLang); + \RainLoop\Utils::ReadAndAddLang(APP_VERSION_ROOT_PATH.'app/localization/'. + ($bAdmin ? 'admin' : 'webmail').'/_source.en.yml', $aResultLang); + \RainLoop\Utils::ReadAndAddLang(APP_VERSION_ROOT_PATH.'app/localization/'. + ($bAdmin ? 'admin' : 'webmail').'/'.$sLanguage.'.yml', $aResultLang); + + $this->Plugins()->ReadLang($sLanguage, $aResultLang); + + $sLangJs = ''; + $aLangKeys = \array_keys($aResultLang); + foreach ($aLangKeys as $sKey) + { + $sString = isset($aResultLang[$sKey]) ? $aResultLang[$sKey] : $sKey; + if (\is_array($sString)) + { + $sString = \implode("\n", $sString); + } + + $sLangJs .= '"'.\str_replace('"', '\\"', \str_replace('\\', '\\\\', $sKey)).'":' + .'"'.\str_replace(array("\r", "\n", "\t"), array('\r', '\n', '\t'), + \str_replace('"', '\\"', \str_replace('\\', '\\\\', $sString))).'",'; + } + + $sResult = empty($sLangJs) ? 'null' : '{'.\substr($sLangJs, 0, -1).'}'; + + return + ($bWrapByScriptTag ? '' : '') + ; + } + + /** + * @param array $aAppData + * @param bool $bWrapByScriptTag = true + * + * @return string + */ + private function compileAppData($aAppData, $bWrapByScriptTag = true) + { + return + ($bWrapByScriptTag ? '' : '') + ; + } +} diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/RainLoop/Settings.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/RainLoop/Settings.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/RainLoop/Settings.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/RainLoop/Settings.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/RainLoop/Social.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/RainLoop/Social.php similarity index 96% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/RainLoop/Social.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/RainLoop/Social.php index a1363756bd77c05b9cb622b665dd9f09b491f7d1..d19164f81ef34a3d8912b36bf6f60c0ae0e312d0 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/RainLoop/Social.php +++ b/rainloop/app/rainloop/v/1.12.1/app/libraries/RainLoop/Social.php @@ -1,792 +1,792 @@ -oHttp = $oHttp; - $this->oActions = $oActions; - } - - /** - * @return bool - */ - public function GoogleDisconnect($oAccount) - { - $oGoogle = $this->GoogleConnector(); - if ($oAccount && $oGoogle) - { - $oSettings = $this->oActions->SettingsProvider()->Load($oAccount); - $sEncodedeData = $oSettings->GetConf('GoogleAccessToken', ''); - - if (!empty($sEncodedeData)) - { - $aData = \RainLoop\Utils::DecodeKeyValues($sEncodedeData); - if (\is_array($aData) && !empty($aData['id'])) - { - $this->oActions->StorageProvider()->Clear(null, - \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, - $this->GoogleUserLoginStorageKey($oGoogle, $aData['id']) - ); - } - } - - $oSettings->SetConf('GoogleAccessToken', ''); - $oSettings->SetConf('GoogleSocialName', ''); - - return $this->oActions->SettingsProvider()->Save($oAccount, $oSettings); - } - - return false; - } - - /** - * @return bool - */ - public function FacebookDisconnect($oAccount) - { - $oFacebook = $this->FacebookConnector($oAccount ? $oAccount : null); - if ($oAccount && $oFacebook) - { - $oSettings = $this->oActions->SettingsProvider()->Load($oAccount); - - $sEncodedeData = $oSettings->GetConf('FacebookAccessToken', ''); - - if (!empty($sEncodedeData)) - { - $aData = \RainLoop\Utils::DecodeKeyValues($sEncodedeData); - if (is_array($aData) && isset($aData['id'])) - { - $this->oActions->StorageProvider()->Clear(null, - \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, - $this->FacebookUserLoginStorageKey($oFacebook, $aData['id']) - ); - } - } - - $oSettings->SetConf('FacebookAccessToken', ''); - $oSettings->SetConf('FacebookSocialName', ''); - - return $this->oActions->SettingsProvider()->Save($oAccount, $oSettings); - } - - return false; - } - - /** - * @return bool - */ - public function TwitterDisconnect($oAccount) - { - $oTwitter = $this->TwitterConnector(); - if ($oAccount && $oTwitter) - { - $oSettings = $this->oActions->SettingsProvider()->Load($oAccount); - $sEncodedData = $oSettings->GetConf('TwitterAccessToken', ''); - - if (!empty($sEncodedData)) - { - $aData = \RainLoop\Utils::DecodeKeyValues($sEncodedData); - if (is_array($aData) && isset($aData['id'])) - { - $this->oActions->StorageProvider()->Clear(null, - \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, - $this->TwitterUserLoginStorageKey($oTwitter, $aData['id']) - ); - } - } - - $oSettings->SetConf('TwitterAccessToken', ''); - $oSettings->SetConf('TwitterSocialName', ''); - - return $this->oActions->SettingsProvider()->Save($oAccount, $oSettings); - } - - return false; - } - - /** - * @return string - */ - public function popupServiceResult($sTypeStr, $sLoginUrl, $bLogin, $iErrorCode) - { - $sResult = ''; - $bAppCssDebug = !!$this->oActions->Config()->Get('labs', 'use_app_debug_css', false); - - $sIcon = $sTypeStr; - if ('facebook' === $sIcon) - { - $sIcon = $sIcon.'-alt'; - } - - if ($sLoginUrl) - { - $this->oHttp->ServerNoCache(); - @\header('Content-Type: text/html; charset=utf-8'); - - $sResult = \strtr(\file_get_contents(APP_VERSION_ROOT_PATH.'app/templates/Social.html'), array( - '{{RefreshMeta}}' => '', - '{{Stylesheet}}' => $this->oActions->StaticPath('css/social'.($bAppCssDebug ? '' : '.min').'.css'), - '{{Icon}}' => $sIcon, - '{{Script}}' => '' - )); - } - else - { - $this->oHttp->ServerNoCache(); - @\header('Content-Type: text/html; charset=utf-8'); - - $sCallBackType = $bLogin ? '_login' : ''; - $sConnectionFunc = 'rl_'.\md5(\RainLoop\Utils::GetConnectionToken()).'_'.$sTypeStr.$sCallBackType.'_service'; - - $sResult = \strtr(\file_get_contents(APP_VERSION_ROOT_PATH.'app/templates/Social.html'), array( - '{{RefreshMeta}}' => '', - '{{Stylesheet}}' => $this->oActions->StaticPath('css/social'.($bAppCssDebug ? '' : '.min').'.css'), - '{{Icon}}' => $sIcon, - '{{Script}}' => '' - )); - } - - return $sResult; - } - - /** - * @return string - */ - public function GooglePopupService($bGmail = false) - { - $sLoginUrl = ''; - $oAccount = null; - - $bLogin = false; - $iErrorCode = \RainLoop\Notifications::UnknownError; - - try - { - $oGoogle = $this->GoogleConnector(); - if ($this->oHttp->HasQuery('error')) - { - $iErrorCode = ('access_denied' === $this->oHttp->GetQuery('error')) ? - \RainLoop\Notifications::SocialGoogleLoginAccessDisable : \RainLoop\Notifications::UnknownError; - } - else if ($oGoogle) - { - $oAccount = $this->oActions->GetAccount(); - $bLogin = !$oAccount; - - $sCheckToken = ''; - $sCheckAuth = ''; - $sState = $this->oHttp->GetQuery('state'); - if (!empty($sState)) - { - $aParts = explode('|', $sState, 3); - - if (!$bGmail) - { - $bGmail = !empty($aParts[0]) ? '1' === (string) $aParts[0] : false; - } - - $sCheckToken = !empty($aParts[1]) ? $aParts[1] : ''; - $sCheckAuth = !empty($aParts[2]) ? $aParts[2] : ''; - } - - $sRedirectUrl = $this->oHttp->GetFullUrl().'?SocialGoogle'; - if (!$this->oHttp->HasQuery('code')) - { - $aParams = array( - 'scope' => \trim(\implode(' ', array( - 'https://www.googleapis.com/auth/userinfo.email', - 'https://www.googleapis.com/auth/userinfo.profile', - $bGmail ? 'https://mail.google.com/' : '' - ))), - 'state' => ($bGmail ? '1' : '0').'|'.\RainLoop\Utils::GetConnectionToken().'|'.$this->oActions->GetSpecAuthToken(), - 'response_type' => 'code' - ); - -// if ($bGmail) -// { -// $aParams['access_type'] = 'offline'; -// $aParams['approval_prompt'] = 'force'; -// } - - $sLoginUrl = $oGoogle->getAuthenticationUrl('https://accounts.google.com/o/oauth2/auth', $sRedirectUrl, $aParams); - } - else if (!empty($sState) && $sCheckToken === \RainLoop\Utils::GetConnectionToken()) - { - if (!empty($sCheckAuth)) - { - $this->oActions->SetSpecAuthToken($sCheckAuth); - $oAccount = $this->oActions->GetAccount(); - $bLogin = !$oAccount; - } - - $aParams = array('code' => $this->oHttp->GetQuery('code'), 'redirect_uri' => $sRedirectUrl); - $aAuthorizationResponse = $oGoogle->getAccessToken('https://accounts.google.com/o/oauth2/token', 'authorization_code', $aParams); - - if (!empty($aAuthorizationResponse['result']['access_token'])) - { - $oGoogle->setAccessToken($aAuthorizationResponse['result']['access_token']); - $aUserInfoResponse = $oGoogle->fetch('https://www.googleapis.com/oauth2/v2/userinfo'); - - if (!empty($aUserInfoResponse['result']['id'])) - { - if ($bLogin) - { - $aUserData = null; - if ($bGmail) - { - if (!empty($aUserInfoResponse['result']['email'])) - { - $aUserData = array( - 'Email' => $aUserInfoResponse['result']['email'], - 'Password' => APP_GOOGLE_ACCESS_TOKEN_PREFIX.$aAuthorizationResponse['result']['access_token'] - ); - } - } - else - { - $sUserData = $this->oActions->StorageProvider()->Get(null, - \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, - $this->GoogleUserLoginStorageKey($oGoogle, $aUserInfoResponse['result']['id']) - ); - - $aUserData = \RainLoop\Utils::DecodeKeyValues($sUserData); - } - - if ($aUserData && \is_array($aUserData) && - !empty($aUserData['Email']) && isset($aUserData['Password'])) - { - $iErrorCode = $this->loginProcess($oAccount, $aUserData['Email'], $aUserData['Password']); - } - else - { - $iErrorCode = \RainLoop\Notifications::SocialGoogleLoginAccessDisable; - } - } - - if ($oAccount && !$bGmail) - { - $aUserData = array( - 'ID' => $aUserInfoResponse['result']['id'], - 'Email' => $oAccount->Email(), - 'Password' => $oAccount->Password() - ); - - $sSocialName = !empty($aUserInfoResponse['result']['name']) ? $aUserInfoResponse['result']['name'] : ''; - $sSocialName .= !empty($aUserInfoResponse['result']['email']) ? ' ('.$aUserInfoResponse['result']['email'].')' : ''; - $sSocialName = \trim($sSocialName); - - $oSettings = $this->oActions->SettingsProvider()->Load($oAccount); - - $oSettings->SetConf('GoogleAccessToken', \RainLoop\Utils::EncodeKeyValues(array( - 'id' => $aUserInfoResponse['result']['id'] - ))); - - $oSettings->SetConf('GoogleSocialName', $sSocialName); - - $this->oActions->SettingsProvider()->Save($oAccount, $oSettings); - - $this->oActions->StorageProvider()->Put(null, - \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, - $this->GoogleUserLoginStorageKey($oGoogle, $aUserInfoResponse['result']['id']), - \RainLoop\Utils::EncodeKeyValues($aUserData)); - - $iErrorCode = 0; - } - } - } - } - } - } - catch (\Exception $oException) - { - $this->oActions->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); - } - - return $this->popupServiceResult('google', $sLoginUrl, $bLogin, $iErrorCode); - } - - /** - * @return string - */ - public function FacebookPopupService() - { - $sLoginUrl = ''; - $sSocialName = ''; - - $mData = false; - $sUserData = ''; - $aUserData = false; - $oAccount = null; - - $bLogin = false; - $iErrorCode = \RainLoop\Notifications::UnknownError; - - if (0 === \strlen($this->oActions->GetSpecAuthToken()) && $this->oHttp->HasQuery('rlah')) - { - $this->oActions->SetSpecAuthToken($this->oHttp->GetQuery('rlah', '')); - } - - $oAccount = $this->oActions->GetAccount(); - - $sRedirectUrl = ''; - $oFacebook = $this->FacebookConnector($oAccount, $sRedirectUrl); - if ($oFacebook) - { - try - { - $oRedirectLoginHelper = $oFacebook->getRedirectLoginHelper(); - $oAccessToken = $oRedirectLoginHelper->getAccessToken(); - - if (!$oAccessToken && !$this->oHttp->HasQuery('state')) - { - $sLoginUrl = $oFacebook->getRedirectLoginHelper()->getLoginUrl($sRedirectUrl.'&display=popup'); - } - else if ($oAccessToken) - { - $oResponse = $oFacebook->get('/me?fields=id,name', (string) $oAccessToken); - $oGraphUser = $oResponse->getGraphUser(); - - $mData = $oGraphUser->getId(); - $sSocialName = $oGraphUser->getName(); - - if ($oAccount) - { - if ($mData && 0 < \strlen($mData)) - { - $aUserData = array( - 'id' => $mData, - 'Email' => $oAccount->Email(), - 'Password' => $oAccount->Password() - ); - - $oSettings = $this->oActions->SettingsProvider()->Load($oAccount); - $oSettings->SetConf('FacebookSocialName', $sSocialName); - $oSettings->SetConf('FacebookAccessToken', \RainLoop\Utils::EncodeKeyValues(array('id' => $mData))); - - $this->oActions->SettingsProvider()->Save($oAccount, $oSettings); - - $this->oActions->StorageProvider()->Put(null, - \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, - $this->FacebookUserLoginStorageKey($oFacebook, $mData), - \RainLoop\Utils::EncodeKeyValues($aUserData)); - - $iErrorCode = 0; - } - } - else - { - $bLogin = true; - - if ($mData && 0 < \strlen($mData)) - { - $sUserData = $this->oActions->StorageProvider()->Get(null, - \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, - $this->FacebookUserLoginStorageKey($oFacebook, $mData)); - - if ($sUserData) - { - $aUserData = \RainLoop\Utils::DecodeKeyValues($sUserData); - } - } - - if ($aUserData && \is_array($aUserData) && - !empty($aUserData['Email']) && isset($aUserData['Password'])) - { - $iErrorCode = $this->loginProcess($oAccount, $aUserData['Email'], $aUserData['Password']); - } - else - { - $iErrorCode = \RainLoop\Notifications::SocialFacebookLoginAccessDisable; - } - } - } - } - catch (\Exception $oException) - { - $this->oActions->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); - } - } - - return $this->popupServiceResult('facebook', $sLoginUrl, $bLogin, $iErrorCode); - } - - /** - * @return string - */ - public function TwitterPopupService() - { - $sLoginUrl = ''; - - $sSocialName = ''; - $oAccount = null; - - $bLogin = false; - $iErrorCode = \RainLoop\Notifications::UnknownError; - - $sRedirectUrl = $this->oHttp->GetFullUrl().'?SocialTwitter'; - if (0 < strlen($this->oActions->GetSpecAuthToken())) - { - $sRedirectUrl .= '&rlah='.$this->oActions->GetSpecAuthToken(); - } - else if ($this->oHttp->HasQuery('rlah')) - { - $this->oActions->SetSpecAuthToken($this->oHttp->GetQuery('rlah', '')); - $sRedirectUrl .= '&rlah='.$this->oActions->GetSpecAuthToken(); - } - - try - { - $oTwitter = $this->TwitterConnector(); - if ($oTwitter) - { - $sSessionKey = \implode('_', array('twitter', - \md5($oTwitter->config['consumer_secret']), \md5(\RainLoop\Utils::GetConnectionToken()), 'AuthSessionData')); - - $oAccount = $this->oActions->GetAccount(); - if ($oAccount) - { - if (isset($_REQUEST['oauth_verifier'])) - { - $sAuth = $this->oActions->Cacher()->Get($sSessionKey); - $oAuth = $sAuth ? \json_decode($sAuth, true) : null; - - if ($oAuth && !empty($oAuth['oauth_token']) && !empty($oAuth['oauth_token_secret'])) - { - $oTwitter->config['user_token'] = $oAuth['oauth_token']; - $oTwitter->config['user_secret'] = $oAuth['oauth_token_secret']; - - $iCode = $oTwitter->request('POST', $oTwitter->url('oauth/access_token', ''), array( - 'oauth_callback' => $sRedirectUrl, - 'oauth_verifier' => $_REQUEST['oauth_verifier'] - )); - - if (200 === $iCode && isset($oTwitter->response['response'])) - { - $aAccessToken = $oTwitter->extract_params($oTwitter->response['response']); - if ($aAccessToken && isset($aAccessToken['oauth_token']) && !empty($aAccessToken['user_id'])) - { - $aAccessToken['id'] = $aAccessToken['user_id']; - - $oTwitter->config['user_token'] = $aAccessToken['oauth_token']; - $oTwitter->config['user_secret'] = $aAccessToken['oauth_token_secret']; - - $sSocialName = !empty($aAccessToken['screen_name']) ? '@'.$aAccessToken['screen_name'] : $aAccessToken['user_id']; - $sSocialName = \trim($sSocialName); - - $aUserData = array( - 'id' => $aAccessToken['id'], - 'Email' => $oAccount->Email(), - 'Password' => $oAccount->Password() - ); - - $oSettings = $this->oActions->SettingsProvider()->Load($oAccount); - $oSettings->SetConf('TwitterAccessToken', \RainLoop\Utils::EncodeKeyValues($aAccessToken)); - $oSettings->SetConf('TwitterSocialName', $sSocialName); - $this->oActions->SettingsProvider()->Save($oAccount, $oSettings); - - $this->oActions->StorageProvider()->Put(null, - \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, - $this->TwitterUserLoginStorageKey($oTwitter, $aAccessToken['id']), - \RainLoop\Utils::EncodeKeyValues($aUserData)); - - $iErrorCode = 0; - } - } - } - } - else - { - $aParams = array( - 'oauth_callback' => $sRedirectUrl, - 'x_auth_access_type' => 'read' - ); - - $iCode = $oTwitter->request('POST', $oTwitter->url('oauth/request_token', ''), $aParams); - if (200 === $iCode && isset($oTwitter->response['response'])) - { - $oAuth = $oTwitter->extract_params($oTwitter->response['response']); - if (!empty($oAuth['oauth_token'])) - { - $this->oActions->Cacher()->Set($sSessionKey, \json_encode($oAuth)); - $sLoginUrl = $oTwitter->url('oauth/authenticate', '').'?oauth_token='.$oAuth['oauth_token']; - } - } - } - } - else - { - $bLogin = true; - - if (isset($_REQUEST['oauth_verifier'])) - { - $sAuth = $this->oActions->Cacher()->Get($sSessionKey); - $oAuth = $sAuth ? \json_decode($sAuth, true) : null; - if ($oAuth && !empty($oAuth['oauth_token']) && !empty($oAuth['oauth_token_secret'])) - { - $oTwitter->config['user_token'] = $oAuth['oauth_token']; - $oTwitter->config['user_secret'] = $oAuth['oauth_token_secret']; - - $iCode = $oTwitter->request('POST', $oTwitter->url('oauth/access_token', ''), array( - 'oauth_callback' => $sRedirectUrl, - 'oauth_verifier' => $_REQUEST['oauth_verifier'] - )); - - if (200 === $iCode && isset($oTwitter->response['response'])) - { - $aAccessToken = $oTwitter->extract_params($oTwitter->response['response']); - if ($aAccessToken && isset($aAccessToken['oauth_token']) && !empty($aAccessToken['user_id'])) - { - $sUserData = $this->oActions->StorageProvider()->Get(null, - \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, - $this->TwitterUserLoginStorageKey($oTwitter, $aAccessToken['user_id']) - ); - - $aUserData = \RainLoop\Utils::DecodeKeyValues($sUserData); - - if ($aUserData && \is_array($aUserData) && - !empty($aUserData['Email']) && isset($aUserData['Password'])) - { - $iErrorCode = $this->loginProcess($oAccount, $aUserData['Email'], $aUserData['Password']); - } - else - { - $iErrorCode = \RainLoop\Notifications::SocialTwitterLoginAccessDisable; - } - - $this->oActions->Cacher()->Delete($sSessionKey); - } - } - } - } - else - { - $aParams = array( - 'oauth_callback' => $sRedirectUrl, - 'x_auth_access_type' => 'read' - ); - - $iCode = $oTwitter->request('POST', $oTwitter->url('oauth/request_token', ''), $aParams); - if (200 === $iCode && isset($oTwitter->response['response'])) - { - $oAuth = $oTwitter->extract_params($oTwitter->response['response']); - if (!empty($oAuth['oauth_token'])) - { - $this->oActions->Cacher()->Set($sSessionKey, \json_encode($oAuth)); - $sLoginUrl = $oTwitter->url('oauth/authenticate', '').'?oauth_token='.$oAuth['oauth_token']; - } - } - } - } - } - } - catch (\Exception $oException) - { - $this->oActions->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); - } - - return $this->popupServiceResult('twitter', $sLoginUrl, $bLogin, $iErrorCode); - } - - /** - * @return \OAuth2\Client|null - */ - public function GoogleConnector() - { - $oGoogle = false; - $oConfig = $this->oActions->Config(); - if ($oConfig->Get('social', 'google_enable', false) && - '' !== \trim($oConfig->Get('social', 'google_client_id', '')) && - '' !== \trim($oConfig->Get('social', 'google_client_secret', ''))) - { - include_once APP_VERSION_ROOT_PATH.'app/libraries/PHP-OAuth2/Client.php'; - include_once APP_VERSION_ROOT_PATH.'app/libraries/PHP-OAuth2/GrantType/IGrantType.php'; - include_once APP_VERSION_ROOT_PATH.'app/libraries/PHP-OAuth2/GrantType/AuthorizationCode.php'; - include_once APP_VERSION_ROOT_PATH.'app/libraries/PHP-OAuth2/GrantType/RefreshToken.php'; - - try - { - $oGoogle = new \OAuth2\Client( - \trim($oConfig->Get('social', 'google_client_id', '')), - \trim($oConfig->Get('social', 'google_client_secret', ''))); - - $sProxy = $this->oActions->Config()->Get('labs', 'curl_proxy', ''); - if (0 < \strlen($sProxy)) - { - $oGoogle->setCurlOption(CURLOPT_PROXY, $sProxy); - - $sProxyAuth = $this->oActions->Config()->Get('labs', 'curl_proxy_auth', ''); - if (0 < \strlen($sProxyAuth)) - { - $oGoogle->setCurlOption(CURLOPT_PROXYUSERPWD, $sProxyAuth); - } - } - } - catch (\Exception $oException) - { - $this->oActions->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); - } - } - - return false === $oGoogle ? null : $oGoogle; - } - - /** - * @return \tmhOAuth|null - */ - public function TwitterConnector() - { - $oTwitter = false; - $oConfig = $this->oActions->Config(); - if ($oConfig->Get('social', 'twitter_enable', false) && - '' !== \trim($oConfig->Get('social', 'twitter_consumer_key', '')) && - '' !== \trim($oConfig->Get('social', 'twitter_consumer_secret', ''))) - { - include_once APP_VERSION_ROOT_PATH.'app/libraries/tmhOAuth/tmhOAuth.php'; - include_once APP_VERSION_ROOT_PATH.'app/libraries/tmhOAuth/tmhUtilities.php'; - - $sProxy = $this->oActions->Config()->Get('labs', 'curl_proxy', ''); - $sProxyAuth = $this->oActions->Config()->Get('labs', 'curl_proxy_auth', ''); - - $oTwitter = new \tmhOAuth(array( - 'consumer_key' => \trim($oConfig->Get('social', 'twitter_consumer_key', '')), - 'consumer_secret' => \trim($oConfig->Get('social', 'twitter_consumer_secret', '')), - 'curl_proxy' => 0 < \strlen($sProxy) ? $sProxy : false, - 'curl_proxyuserpwd' => 0 < \strlen($sProxyAuth) ? $sProxyAuth : false - )); - } - - return false === $oTwitter ? null : $oTwitter; - } - - /** - * @param \RainLoop\Model\Account|null $oAccount = null - * @param string $sRedirectUrl = '' - * - * @return \RainLoop\Common\RainLoopFacebookRedirectLoginHelper|null - */ - public function FacebookConnector($oAccount = null, &$sRedirectUrl = '') - { - $oFacebook = false; - $oConfig = $this->oActions->Config(); - $sAppID = \trim($oConfig->Get('social', 'fb_app_id', '')); - $sAppSecret = \trim($oConfig->Get('social', 'fb_app_secret', '')); - - if (\version_compare(PHP_VERSION, '5.4.0', '>=') && - $oConfig->Get('social', 'fb_enable', false) && '' !== $sAppID && - '' !== \trim($oConfig->Get('social', 'fb_app_secret', '')) && - \class_exists('Facebook\Facebook') - ) - { - $sRedirectUrl = $this->oHttp->GetFullUrl().'?SocialFacebook'; - if (0 < \strlen($this->oActions->GetSpecAuthToken())) - { - $sRedirectUrl .= '&rlah='.$this->oActions->GetSpecAuthToken(); - } - else if ($this->oHttp->HasQuery('rlah')) - { - $this->oActions->SetSpecAuthToken($this->oHttp->GetQuery('rlah', '')); - $sRedirectUrl .= '&rlah='.$this->oActions->GetSpecAuthToken(); - } - - try - { - $oAccount = $this->oActions->GetAccount(); - - $oFacebook = new \Facebook\Facebook(array( - 'app_id' => $sAppID, // Replace {app-id} with your app id - 'app_secret' => $sAppSecret, - 'persistent_data_handler' => new \RainLoop\Common\FacebookRainLoopPersistentDataHandler( - $oAccount, \RainLoop\Utils::GetConnectionToken(), $this->oActions->StorageProvider() - ) - )); - } - catch (\Exception $oException) - { - $this->oActions->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); - } - } - - return false === $oFacebook ? null : $oFacebook; - } - - /** - * @return string - */ - public function GoogleUserLoginStorageKey($oGoogle, $sGoogleUserId) - { - return \implode('_', array('google', \md5($oGoogle->getClientId()), $sGoogleUserId, APP_SALT)); - } - - /** - * @return string - */ - public function FacebookUserLoginStorageKey($oFacebook, $sFacebookUserId) - { - return \implode('_', array('facebookNew', \md5($oFacebook->getApp()->getId()), $sFacebookUserId, APP_SALT)); - } - - /** - * @return string - */ - public function TwitterUserLoginStorageKey($oTwitter, $sTwitterUserId) - { - return \implode('_', array('twitter_2', \md5($oTwitter->config['consumer_secret']), $sTwitterUserId, APP_SALT)); - } - - /** - * @param \RainLoop\Model\Account|null $oAccount - * @param string $sEmail - * @param string $sPassword - * - * @return int - */ - private function loginProcess(&$oAccount, $sEmail, $sPassword) - { - $iErrorCode = \RainLoop\Notifications::UnknownError; - - try - { - $oAccount = $this->oActions->LoginProcess($sEmail, $sPassword, '', '', false, true); - if ($oAccount instanceof \RainLoop\Model\Account) - { - $this->oActions->AuthToken($oAccount); - $iErrorCode = 0; - } - else - { - $oAccount = null; - $iErrorCode = \RainLoop\Notifications::AuthError; - } - } - catch (\RainLoop\Exceptions\ClientException $oException) - { - $iErrorCode = $oException->getCode(); - } - catch (\Exception $oException) - { - unset($oException); - $iErrorCode = \RainLoop\Notifications::UnknownError; - } - - return $iErrorCode; - } +oHttp = $oHttp; + $this->oActions = $oActions; + } + + /** + * @return bool + */ + public function GoogleDisconnect($oAccount) + { + $oGoogle = $this->GoogleConnector(); + if ($oAccount && $oGoogle) + { + $oSettings = $this->oActions->SettingsProvider()->Load($oAccount); + $sEncodedeData = $oSettings->GetConf('GoogleAccessToken', ''); + + if (!empty($sEncodedeData)) + { + $aData = \RainLoop\Utils::DecodeKeyValues($sEncodedeData); + if (\is_array($aData) && !empty($aData['id'])) + { + $this->oActions->StorageProvider()->Clear(null, + \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, + $this->GoogleUserLoginStorageKey($oGoogle, $aData['id']) + ); + } + } + + $oSettings->SetConf('GoogleAccessToken', ''); + $oSettings->SetConf('GoogleSocialName', ''); + + return $this->oActions->SettingsProvider()->Save($oAccount, $oSettings); + } + + return false; + } + + /** + * @return bool + */ + public function FacebookDisconnect($oAccount) + { + $oFacebook = $this->FacebookConnector($oAccount ? $oAccount : null); + if ($oAccount && $oFacebook) + { + $oSettings = $this->oActions->SettingsProvider()->Load($oAccount); + + $sEncodedeData = $oSettings->GetConf('FacebookAccessToken', ''); + + if (!empty($sEncodedeData)) + { + $aData = \RainLoop\Utils::DecodeKeyValues($sEncodedeData); + if (is_array($aData) && isset($aData['id'])) + { + $this->oActions->StorageProvider()->Clear(null, + \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, + $this->FacebookUserLoginStorageKey($oFacebook, $aData['id']) + ); + } + } + + $oSettings->SetConf('FacebookAccessToken', ''); + $oSettings->SetConf('FacebookSocialName', ''); + + return $this->oActions->SettingsProvider()->Save($oAccount, $oSettings); + } + + return false; + } + + /** + * @return bool + */ + public function TwitterDisconnect($oAccount) + { + $oTwitter = $this->TwitterConnector(); + if ($oAccount && $oTwitter) + { + $oSettings = $this->oActions->SettingsProvider()->Load($oAccount); + $sEncodedData = $oSettings->GetConf('TwitterAccessToken', ''); + + if (!empty($sEncodedData)) + { + $aData = \RainLoop\Utils::DecodeKeyValues($sEncodedData); + if (is_array($aData) && isset($aData['id'])) + { + $this->oActions->StorageProvider()->Clear(null, + \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, + $this->TwitterUserLoginStorageKey($oTwitter, $aData['id']) + ); + } + } + + $oSettings->SetConf('TwitterAccessToken', ''); + $oSettings->SetConf('TwitterSocialName', ''); + + return $this->oActions->SettingsProvider()->Save($oAccount, $oSettings); + } + + return false; + } + + /** + * @return string + */ + public function popupServiceResult($sTypeStr, $sLoginUrl, $bLogin, $iErrorCode) + { + $sResult = ''; + $bAppCssDebug = !!$this->oActions->Config()->Get('labs', 'use_app_debug_css', false); + + $sIcon = $sTypeStr; + if ('facebook' === $sIcon) + { + $sIcon = $sIcon.'-alt'; + } + + if ($sLoginUrl) + { + $this->oHttp->ServerNoCache(); + @\header('Content-Type: text/html; charset=utf-8'); + + $sResult = \strtr(\file_get_contents(APP_VERSION_ROOT_PATH.'app/templates/Social.html'), array( + '{{RefreshMeta}}' => '', + '{{Stylesheet}}' => $this->oActions->StaticPath('css/social'.($bAppCssDebug ? '' : '.min').'.css'), + '{{Icon}}' => $sIcon, + '{{Script}}' => '' + )); + } + else + { + $this->oHttp->ServerNoCache(); + @\header('Content-Type: text/html; charset=utf-8'); + + $sCallBackType = $bLogin ? '_login' : ''; + $sConnectionFunc = 'rl_'.\md5(\RainLoop\Utils::GetConnectionToken()).'_'.$sTypeStr.$sCallBackType.'_service'; + + $sResult = \strtr(\file_get_contents(APP_VERSION_ROOT_PATH.'app/templates/Social.html'), array( + '{{RefreshMeta}}' => '', + '{{Stylesheet}}' => $this->oActions->StaticPath('css/social'.($bAppCssDebug ? '' : '.min').'.css'), + '{{Icon}}' => $sIcon, + '{{Script}}' => '' + )); + } + + return $sResult; + } + + /** + * @return string + */ + public function GooglePopupService($bGmail = false) + { + $sLoginUrl = ''; + $oAccount = null; + + $bLogin = false; + $iErrorCode = \RainLoop\Notifications::UnknownError; + + try + { + $oGoogle = $this->GoogleConnector(); + if ($this->oHttp->HasQuery('error')) + { + $iErrorCode = ('access_denied' === $this->oHttp->GetQuery('error')) ? + \RainLoop\Notifications::SocialGoogleLoginAccessDisable : \RainLoop\Notifications::UnknownError; + } + else if ($oGoogle) + { + $oAccount = $this->oActions->GetAccount(); + $bLogin = !$oAccount; + + $sCheckToken = ''; + $sCheckAuth = ''; + $sState = $this->oHttp->GetQuery('state'); + if (!empty($sState)) + { + $aParts = explode('|', $sState, 3); + + if (!$bGmail) + { + $bGmail = !empty($aParts[0]) ? '1' === (string) $aParts[0] : false; + } + + $sCheckToken = !empty($aParts[1]) ? $aParts[1] : ''; + $sCheckAuth = !empty($aParts[2]) ? $aParts[2] : ''; + } + + $sRedirectUrl = $this->oHttp->GetFullUrl().'?SocialGoogle'; + if (!$this->oHttp->HasQuery('code')) + { + $aParams = array( + 'scope' => \trim(\implode(' ', array( + 'https://www.googleapis.com/auth/userinfo.email', + 'https://www.googleapis.com/auth/userinfo.profile', + $bGmail ? 'https://mail.google.com/' : '' + ))), + 'state' => ($bGmail ? '1' : '0').'|'.\RainLoop\Utils::GetConnectionToken().'|'.$this->oActions->GetSpecAuthToken(), + 'response_type' => 'code' + ); + +// if ($bGmail) +// { +// $aParams['access_type'] = 'offline'; +// $aParams['approval_prompt'] = 'force'; +// } + + $sLoginUrl = $oGoogle->getAuthenticationUrl('https://accounts.google.com/o/oauth2/auth', $sRedirectUrl, $aParams); + } + else if (!empty($sState) && $sCheckToken === \RainLoop\Utils::GetConnectionToken()) + { + if (!empty($sCheckAuth)) + { + $this->oActions->SetSpecAuthToken($sCheckAuth); + $oAccount = $this->oActions->GetAccount(); + $bLogin = !$oAccount; + } + + $aParams = array('code' => $this->oHttp->GetQuery('code'), 'redirect_uri' => $sRedirectUrl); + $aAuthorizationResponse = $oGoogle->getAccessToken('https://accounts.google.com/o/oauth2/token', 'authorization_code', $aParams); + + if (!empty($aAuthorizationResponse['result']['access_token'])) + { + $oGoogle->setAccessToken($aAuthorizationResponse['result']['access_token']); + $aUserInfoResponse = $oGoogle->fetch('https://www.googleapis.com/oauth2/v2/userinfo'); + + if (!empty($aUserInfoResponse['result']['id'])) + { + if ($bLogin) + { + $aUserData = null; + if ($bGmail) + { + if (!empty($aUserInfoResponse['result']['email'])) + { + $aUserData = array( + 'Email' => $aUserInfoResponse['result']['email'], + 'Password' => APP_GOOGLE_ACCESS_TOKEN_PREFIX.$aAuthorizationResponse['result']['access_token'] + ); + } + } + else + { + $sUserData = $this->oActions->StorageProvider()->Get(null, + \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, + $this->GoogleUserLoginStorageKey($oGoogle, $aUserInfoResponse['result']['id']) + ); + + $aUserData = \RainLoop\Utils::DecodeKeyValues($sUserData); + } + + if ($aUserData && \is_array($aUserData) && + !empty($aUserData['Email']) && isset($aUserData['Password'])) + { + $iErrorCode = $this->loginProcess($oAccount, $aUserData['Email'], $aUserData['Password']); + } + else + { + $iErrorCode = \RainLoop\Notifications::SocialGoogleLoginAccessDisable; + } + } + + if ($oAccount && !$bGmail) + { + $aUserData = array( + 'ID' => $aUserInfoResponse['result']['id'], + 'Email' => $oAccount->Email(), + 'Password' => $oAccount->Password() + ); + + $sSocialName = !empty($aUserInfoResponse['result']['name']) ? $aUserInfoResponse['result']['name'] : ''; + $sSocialName .= !empty($aUserInfoResponse['result']['email']) ? ' ('.$aUserInfoResponse['result']['email'].')' : ''; + $sSocialName = \trim($sSocialName); + + $oSettings = $this->oActions->SettingsProvider()->Load($oAccount); + + $oSettings->SetConf('GoogleAccessToken', \RainLoop\Utils::EncodeKeyValues(array( + 'id' => $aUserInfoResponse['result']['id'] + ))); + + $oSettings->SetConf('GoogleSocialName', $sSocialName); + + $this->oActions->SettingsProvider()->Save($oAccount, $oSettings); + + $this->oActions->StorageProvider()->Put(null, + \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, + $this->GoogleUserLoginStorageKey($oGoogle, $aUserInfoResponse['result']['id']), + \RainLoop\Utils::EncodeKeyValues($aUserData)); + + $iErrorCode = 0; + } + } + } + } + } + } + catch (\Exception $oException) + { + $this->oActions->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); + } + + return $this->popupServiceResult('google', $sLoginUrl, $bLogin, $iErrorCode); + } + + /** + * @return string + */ + public function FacebookPopupService() + { + $sLoginUrl = ''; + $sSocialName = ''; + + $mData = false; + $sUserData = ''; + $aUserData = false; + $oAccount = null; + + $bLogin = false; + $iErrorCode = \RainLoop\Notifications::UnknownError; + + if (0 === \strlen($this->oActions->GetSpecAuthToken()) && $this->oHttp->HasQuery('rlah')) + { + $this->oActions->SetSpecAuthToken($this->oHttp->GetQuery('rlah', '')); + } + + $oAccount = $this->oActions->GetAccount(); + + $sRedirectUrl = ''; + $oFacebook = $this->FacebookConnector($oAccount, $sRedirectUrl); + if ($oFacebook) + { + try + { + $oRedirectLoginHelper = $oFacebook->getRedirectLoginHelper(); + $oAccessToken = $oRedirectLoginHelper->getAccessToken(); + + if (!$oAccessToken && !$this->oHttp->HasQuery('state')) + { + $sLoginUrl = $oFacebook->getRedirectLoginHelper()->getLoginUrl($sRedirectUrl.'&display=popup'); + } + else if ($oAccessToken) + { + $oResponse = $oFacebook->get('/me?fields=id,name', (string) $oAccessToken); + $oGraphUser = $oResponse->getGraphUser(); + + $mData = $oGraphUser->getId(); + $sSocialName = $oGraphUser->getName(); + + if ($oAccount) + { + if ($mData && 0 < \strlen($mData)) + { + $aUserData = array( + 'id' => $mData, + 'Email' => $oAccount->Email(), + 'Password' => $oAccount->Password() + ); + + $oSettings = $this->oActions->SettingsProvider()->Load($oAccount); + $oSettings->SetConf('FacebookSocialName', $sSocialName); + $oSettings->SetConf('FacebookAccessToken', \RainLoop\Utils::EncodeKeyValues(array('id' => $mData))); + + $this->oActions->SettingsProvider()->Save($oAccount, $oSettings); + + $this->oActions->StorageProvider()->Put(null, + \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, + $this->FacebookUserLoginStorageKey($oFacebook, $mData), + \RainLoop\Utils::EncodeKeyValues($aUserData)); + + $iErrorCode = 0; + } + } + else + { + $bLogin = true; + + if ($mData && 0 < \strlen($mData)) + { + $sUserData = $this->oActions->StorageProvider()->Get(null, + \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, + $this->FacebookUserLoginStorageKey($oFacebook, $mData)); + + if ($sUserData) + { + $aUserData = \RainLoop\Utils::DecodeKeyValues($sUserData); + } + } + + if ($aUserData && \is_array($aUserData) && + !empty($aUserData['Email']) && isset($aUserData['Password'])) + { + $iErrorCode = $this->loginProcess($oAccount, $aUserData['Email'], $aUserData['Password']); + } + else + { + $iErrorCode = \RainLoop\Notifications::SocialFacebookLoginAccessDisable; + } + } + } + } + catch (\Exception $oException) + { + $this->oActions->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); + } + } + + return $this->popupServiceResult('facebook', $sLoginUrl, $bLogin, $iErrorCode); + } + + /** + * @return string + */ + public function TwitterPopupService() + { + $sLoginUrl = ''; + + $sSocialName = ''; + $oAccount = null; + + $bLogin = false; + $iErrorCode = \RainLoop\Notifications::UnknownError; + + $sRedirectUrl = $this->oHttp->GetFullUrl().'?SocialTwitter'; + if (0 < strlen($this->oActions->GetSpecAuthToken())) + { + $sRedirectUrl .= '&rlah='.$this->oActions->GetSpecAuthToken(); + } + else if ($this->oHttp->HasQuery('rlah')) + { + $this->oActions->SetSpecAuthToken($this->oHttp->GetQuery('rlah', '')); + $sRedirectUrl .= '&rlah='.$this->oActions->GetSpecAuthToken(); + } + + try + { + $oTwitter = $this->TwitterConnector(); + if ($oTwitter) + { + $sSessionKey = \implode('_', array('twitter', + \md5($oTwitter->config['consumer_secret']), \md5(\RainLoop\Utils::GetConnectionToken()), 'AuthSessionData')); + + $oAccount = $this->oActions->GetAccount(); + if ($oAccount) + { + if (isset($_REQUEST['oauth_verifier'])) + { + $sAuth = $this->oActions->Cacher()->Get($sSessionKey); + $oAuth = $sAuth ? \json_decode($sAuth, true) : null; + + if ($oAuth && !empty($oAuth['oauth_token']) && !empty($oAuth['oauth_token_secret'])) + { + $oTwitter->config['user_token'] = $oAuth['oauth_token']; + $oTwitter->config['user_secret'] = $oAuth['oauth_token_secret']; + + $iCode = $oTwitter->request('POST', $oTwitter->url('oauth/access_token', ''), array( + 'oauth_callback' => $sRedirectUrl, + 'oauth_verifier' => $_REQUEST['oauth_verifier'] + )); + + if (200 === $iCode && isset($oTwitter->response['response'])) + { + $aAccessToken = $oTwitter->extract_params($oTwitter->response['response']); + if ($aAccessToken && isset($aAccessToken['oauth_token']) && !empty($aAccessToken['user_id'])) + { + $aAccessToken['id'] = $aAccessToken['user_id']; + + $oTwitter->config['user_token'] = $aAccessToken['oauth_token']; + $oTwitter->config['user_secret'] = $aAccessToken['oauth_token_secret']; + + $sSocialName = !empty($aAccessToken['screen_name']) ? '@'.$aAccessToken['screen_name'] : $aAccessToken['user_id']; + $sSocialName = \trim($sSocialName); + + $aUserData = array( + 'id' => $aAccessToken['id'], + 'Email' => $oAccount->Email(), + 'Password' => $oAccount->Password() + ); + + $oSettings = $this->oActions->SettingsProvider()->Load($oAccount); + $oSettings->SetConf('TwitterAccessToken', \RainLoop\Utils::EncodeKeyValues($aAccessToken)); + $oSettings->SetConf('TwitterSocialName', $sSocialName); + $this->oActions->SettingsProvider()->Save($oAccount, $oSettings); + + $this->oActions->StorageProvider()->Put(null, + \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, + $this->TwitterUserLoginStorageKey($oTwitter, $aAccessToken['id']), + \RainLoop\Utils::EncodeKeyValues($aUserData)); + + $iErrorCode = 0; + } + } + } + } + else + { + $aParams = array( + 'oauth_callback' => $sRedirectUrl, + 'x_auth_access_type' => 'read' + ); + + $iCode = $oTwitter->request('POST', $oTwitter->url('oauth/request_token', ''), $aParams); + if (200 === $iCode && isset($oTwitter->response['response'])) + { + $oAuth = $oTwitter->extract_params($oTwitter->response['response']); + if (!empty($oAuth['oauth_token'])) + { + $this->oActions->Cacher()->Set($sSessionKey, \json_encode($oAuth)); + $sLoginUrl = $oTwitter->url('oauth/authenticate', '').'?oauth_token='.$oAuth['oauth_token']; + } + } + } + } + else + { + $bLogin = true; + + if (isset($_REQUEST['oauth_verifier'])) + { + $sAuth = $this->oActions->Cacher()->Get($sSessionKey); + $oAuth = $sAuth ? \json_decode($sAuth, true) : null; + if ($oAuth && !empty($oAuth['oauth_token']) && !empty($oAuth['oauth_token_secret'])) + { + $oTwitter->config['user_token'] = $oAuth['oauth_token']; + $oTwitter->config['user_secret'] = $oAuth['oauth_token_secret']; + + $iCode = $oTwitter->request('POST', $oTwitter->url('oauth/access_token', ''), array( + 'oauth_callback' => $sRedirectUrl, + 'oauth_verifier' => $_REQUEST['oauth_verifier'] + )); + + if (200 === $iCode && isset($oTwitter->response['response'])) + { + $aAccessToken = $oTwitter->extract_params($oTwitter->response['response']); + if ($aAccessToken && isset($aAccessToken['oauth_token']) && !empty($aAccessToken['user_id'])) + { + $sUserData = $this->oActions->StorageProvider()->Get(null, + \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, + $this->TwitterUserLoginStorageKey($oTwitter, $aAccessToken['user_id']) + ); + + $aUserData = \RainLoop\Utils::DecodeKeyValues($sUserData); + + if ($aUserData && \is_array($aUserData) && + !empty($aUserData['Email']) && isset($aUserData['Password'])) + { + $iErrorCode = $this->loginProcess($oAccount, $aUserData['Email'], $aUserData['Password']); + } + else + { + $iErrorCode = \RainLoop\Notifications::SocialTwitterLoginAccessDisable; + } + + $this->oActions->Cacher()->Delete($sSessionKey); + } + } + } + } + else + { + $aParams = array( + 'oauth_callback' => $sRedirectUrl, + 'x_auth_access_type' => 'read' + ); + + $iCode = $oTwitter->request('POST', $oTwitter->url('oauth/request_token', ''), $aParams); + if (200 === $iCode && isset($oTwitter->response['response'])) + { + $oAuth = $oTwitter->extract_params($oTwitter->response['response']); + if (!empty($oAuth['oauth_token'])) + { + $this->oActions->Cacher()->Set($sSessionKey, \json_encode($oAuth)); + $sLoginUrl = $oTwitter->url('oauth/authenticate', '').'?oauth_token='.$oAuth['oauth_token']; + } + } + } + } + } + } + catch (\Exception $oException) + { + $this->oActions->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); + } + + return $this->popupServiceResult('twitter', $sLoginUrl, $bLogin, $iErrorCode); + } + + /** + * @return \OAuth2\Client|null + */ + public function GoogleConnector() + { + $oGoogle = false; + $oConfig = $this->oActions->Config(); + if ($oConfig->Get('social', 'google_enable', false) && + '' !== \trim($oConfig->Get('social', 'google_client_id', '')) && + '' !== \trim($oConfig->Get('social', 'google_client_secret', ''))) + { + include_once APP_VERSION_ROOT_PATH.'app/libraries/PHP-OAuth2/Client.php'; + include_once APP_VERSION_ROOT_PATH.'app/libraries/PHP-OAuth2/GrantType/IGrantType.php'; + include_once APP_VERSION_ROOT_PATH.'app/libraries/PHP-OAuth2/GrantType/AuthorizationCode.php'; + include_once APP_VERSION_ROOT_PATH.'app/libraries/PHP-OAuth2/GrantType/RefreshToken.php'; + + try + { + $oGoogle = new \OAuth2\Client( + \trim($oConfig->Get('social', 'google_client_id', '')), + \trim($oConfig->Get('social', 'google_client_secret', ''))); + + $sProxy = $this->oActions->Config()->Get('labs', 'curl_proxy', ''); + if (0 < \strlen($sProxy)) + { + $oGoogle->setCurlOption(CURLOPT_PROXY, $sProxy); + + $sProxyAuth = $this->oActions->Config()->Get('labs', 'curl_proxy_auth', ''); + if (0 < \strlen($sProxyAuth)) + { + $oGoogle->setCurlOption(CURLOPT_PROXYUSERPWD, $sProxyAuth); + } + } + } + catch (\Exception $oException) + { + $this->oActions->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); + } + } + + return false === $oGoogle ? null : $oGoogle; + } + + /** + * @return \tmhOAuth|null + */ + public function TwitterConnector() + { + $oTwitter = false; + $oConfig = $this->oActions->Config(); + if ($oConfig->Get('social', 'twitter_enable', false) && + '' !== \trim($oConfig->Get('social', 'twitter_consumer_key', '')) && + '' !== \trim($oConfig->Get('social', 'twitter_consumer_secret', ''))) + { + include_once APP_VERSION_ROOT_PATH.'app/libraries/tmhOAuth/tmhOAuth.php'; + include_once APP_VERSION_ROOT_PATH.'app/libraries/tmhOAuth/tmhUtilities.php'; + + $sProxy = $this->oActions->Config()->Get('labs', 'curl_proxy', ''); + $sProxyAuth = $this->oActions->Config()->Get('labs', 'curl_proxy_auth', ''); + + $oTwitter = new \tmhOAuth(array( + 'consumer_key' => \trim($oConfig->Get('social', 'twitter_consumer_key', '')), + 'consumer_secret' => \trim($oConfig->Get('social', 'twitter_consumer_secret', '')), + 'curl_proxy' => 0 < \strlen($sProxy) ? $sProxy : false, + 'curl_proxyuserpwd' => 0 < \strlen($sProxyAuth) ? $sProxyAuth : false + )); + } + + return false === $oTwitter ? null : $oTwitter; + } + + /** + * @param \RainLoop\Model\Account|null $oAccount = null + * @param string $sRedirectUrl = '' + * + * @return \RainLoop\Common\RainLoopFacebookRedirectLoginHelper|null + */ + public function FacebookConnector($oAccount = null, &$sRedirectUrl = '') + { + $oFacebook = false; + $oConfig = $this->oActions->Config(); + $sAppID = \trim($oConfig->Get('social', 'fb_app_id', '')); + $sAppSecret = \trim($oConfig->Get('social', 'fb_app_secret', '')); + + if (\version_compare(PHP_VERSION, '5.4.0', '>=') && + $oConfig->Get('social', 'fb_enable', false) && '' !== $sAppID && + '' !== \trim($oConfig->Get('social', 'fb_app_secret', '')) && + \class_exists('Facebook\Facebook') + ) + { + $sRedirectUrl = $this->oHttp->GetFullUrl().'?SocialFacebook'; + if (0 < \strlen($this->oActions->GetSpecAuthToken())) + { + $sRedirectUrl .= '&rlah='.$this->oActions->GetSpecAuthToken(); + } + else if ($this->oHttp->HasQuery('rlah')) + { + $this->oActions->SetSpecAuthToken($this->oHttp->GetQuery('rlah', '')); + $sRedirectUrl .= '&rlah='.$this->oActions->GetSpecAuthToken(); + } + + try + { + $oAccount = $this->oActions->GetAccount(); + + $oFacebook = new \Facebook\Facebook(array( + 'app_id' => $sAppID, // Replace {app-id} with your app id + 'app_secret' => $sAppSecret, + 'persistent_data_handler' => new \RainLoop\Common\FacebookRainLoopPersistentDataHandler( + $oAccount, \RainLoop\Utils::GetConnectionToken(), $this->oActions->StorageProvider() + ) + )); + } + catch (\Exception $oException) + { + $this->oActions->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); + } + } + + return false === $oFacebook ? null : $oFacebook; + } + + /** + * @return string + */ + public function GoogleUserLoginStorageKey($oGoogle, $sGoogleUserId) + { + return \implode('_', array('google', \md5($oGoogle->getClientId()), $sGoogleUserId, APP_SALT)); + } + + /** + * @return string + */ + public function FacebookUserLoginStorageKey($oFacebook, $sFacebookUserId) + { + return \implode('_', array('facebookNew', \md5($oFacebook->getApp()->getId()), $sFacebookUserId, APP_SALT)); + } + + /** + * @return string + */ + public function TwitterUserLoginStorageKey($oTwitter, $sTwitterUserId) + { + return \implode('_', array('twitter_2', \md5($oTwitter->config['consumer_secret']), $sTwitterUserId, APP_SALT)); + } + + /** + * @param \RainLoop\Model\Account|null $oAccount + * @param string $sEmail + * @param string $sPassword + * + * @return int + */ + private function loginProcess(&$oAccount, $sEmail, $sPassword) + { + $iErrorCode = \RainLoop\Notifications::UnknownError; + + try + { + $oAccount = $this->oActions->LoginProcess($sEmail, $sPassword, '', '', false, true); + if ($oAccount instanceof \RainLoop\Model\Account) + { + $this->oActions->AuthToken($oAccount); + $iErrorCode = 0; + } + else + { + $oAccount = null; + $iErrorCode = \RainLoop\Notifications::AuthError; + } + } + catch (\RainLoop\Exceptions\ClientException $oException) + { + $iErrorCode = $oException->getCode(); + } + catch (\Exception $oException) + { + unset($oException); + $iErrorCode = \RainLoop\Notifications::UnknownError; + } + + return $iErrorCode; + } } \ No newline at end of file diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/RainLoop/Utils.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/RainLoop/Utils.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/RainLoop/Utils.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/RainLoop/Utils.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Backend/AbstractBackend.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Backend/AbstractBackend.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Backend/AbstractBackend.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Backend/AbstractBackend.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Backend/BackendInterface.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Backend/BackendInterface.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Backend/BackendInterface.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Backend/BackendInterface.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Backend/NotificationSupport.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Backend/NotificationSupport.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Backend/NotificationSupport.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Backend/NotificationSupport.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Backend/PDO.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Backend/PDO.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Backend/PDO.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Backend/PDO.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Backend/SharingSupport.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Backend/SharingSupport.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Backend/SharingSupport.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Backend/SharingSupport.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Calendar.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Calendar.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Calendar.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Calendar.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/CalendarObject.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/CalendarObject.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/CalendarObject.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/CalendarObject.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/CalendarQueryParser.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/CalendarQueryParser.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/CalendarQueryParser.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/CalendarQueryParser.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/CalendarQueryValidator.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/CalendarQueryValidator.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/CalendarQueryValidator.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/CalendarQueryValidator.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/CalendarRootNode.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/CalendarRootNode.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/CalendarRootNode.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/CalendarRootNode.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Exception/InvalidComponentType.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Exception/InvalidComponentType.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Exception/InvalidComponentType.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Exception/InvalidComponentType.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/ICSExportPlugin.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/ICSExportPlugin.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/ICSExportPlugin.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/ICSExportPlugin.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/ICalendar.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/ICalendar.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/ICalendar.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/ICalendar.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/ICalendarObject.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/ICalendarObject.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/ICalendarObject.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/ICalendarObject.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/IShareableCalendar.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/IShareableCalendar.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/IShareableCalendar.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/IShareableCalendar.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/ISharedCalendar.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/ISharedCalendar.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/ISharedCalendar.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/ISharedCalendar.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Notifications/Collection.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Notifications/Collection.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Notifications/Collection.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Notifications/Collection.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Notifications/ICollection.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Notifications/ICollection.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Notifications/ICollection.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Notifications/ICollection.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Notifications/INode.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Notifications/INode.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Notifications/INode.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Notifications/INode.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Notifications/INotificationType.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Notifications/INotificationType.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Notifications/INotificationType.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Notifications/INotificationType.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Notifications/Node.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Notifications/Node.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Notifications/Node.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Notifications/Node.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Notifications/Notification/Invite.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Notifications/Notification/Invite.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Notifications/Notification/Invite.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Notifications/Notification/Invite.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Notifications/Notification/InviteReply.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Notifications/Notification/InviteReply.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Notifications/Notification/InviteReply.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Notifications/Notification/InviteReply.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Notifications/Notification/SystemStatus.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Notifications/Notification/SystemStatus.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Notifications/Notification/SystemStatus.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Notifications/Notification/SystemStatus.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Plugin.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Plugin.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Plugin.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Plugin.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Principal/Collection.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Principal/Collection.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Principal/Collection.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Principal/Collection.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Principal/IProxyRead.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Principal/IProxyRead.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Principal/IProxyRead.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Principal/IProxyRead.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Principal/IProxyWrite.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Principal/IProxyWrite.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Principal/IProxyWrite.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Principal/IProxyWrite.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Principal/ProxyRead.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Principal/ProxyRead.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Principal/ProxyRead.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Principal/ProxyRead.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Principal/ProxyWrite.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Principal/ProxyWrite.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Principal/ProxyWrite.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Principal/ProxyWrite.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Principal/User.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Principal/User.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Principal/User.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Principal/User.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Property/AllowedSharingModes.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Property/AllowedSharingModes.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Property/AllowedSharingModes.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Property/AllowedSharingModes.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Property/Invite.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Property/Invite.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Property/Invite.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Property/Invite.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Property/ScheduleCalendarTransp.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Property/ScheduleCalendarTransp.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Property/ScheduleCalendarTransp.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Property/ScheduleCalendarTransp.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Property/SupportedCalendarComponentSet.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Property/SupportedCalendarComponentSet.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Property/SupportedCalendarComponentSet.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Property/SupportedCalendarComponentSet.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Property/SupportedCalendarData.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Property/SupportedCalendarData.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Property/SupportedCalendarData.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Property/SupportedCalendarData.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Property/SupportedCollationSet.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Property/SupportedCollationSet.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Property/SupportedCollationSet.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Property/SupportedCollationSet.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Schedule/IMip.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Schedule/IMip.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Schedule/IMip.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Schedule/IMip.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Schedule/IOutbox.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Schedule/IOutbox.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Schedule/IOutbox.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Schedule/IOutbox.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Schedule/Outbox.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Schedule/Outbox.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Schedule/Outbox.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Schedule/Outbox.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/ShareableCalendar.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/ShareableCalendar.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/ShareableCalendar.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/ShareableCalendar.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/SharedCalendar.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/SharedCalendar.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/SharedCalendar.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/SharedCalendar.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/SharingPlugin.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/SharingPlugin.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/SharingPlugin.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/SharingPlugin.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/UserCalendars.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/UserCalendars.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/UserCalendars.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/UserCalendars.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Version.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Version.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CalDAV/Version.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CalDAV/Version.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CardDAV/AddressBook.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CardDAV/AddressBook.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CardDAV/AddressBook.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CardDAV/AddressBook.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CardDAV/AddressBookQueryParser.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CardDAV/AddressBookQueryParser.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CardDAV/AddressBookQueryParser.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CardDAV/AddressBookQueryParser.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CardDAV/AddressBookRoot.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CardDAV/AddressBookRoot.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CardDAV/AddressBookRoot.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CardDAV/AddressBookRoot.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CardDAV/Backend/AbstractBackend.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CardDAV/Backend/AbstractBackend.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CardDAV/Backend/AbstractBackend.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CardDAV/Backend/AbstractBackend.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CardDAV/Backend/BackendInterface.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CardDAV/Backend/BackendInterface.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CardDAV/Backend/BackendInterface.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CardDAV/Backend/BackendInterface.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CardDAV/Backend/PDO.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CardDAV/Backend/PDO.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CardDAV/Backend/PDO.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CardDAV/Backend/PDO.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CardDAV/Card.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CardDAV/Card.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CardDAV/Card.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CardDAV/Card.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CardDAV/IAddressBook.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CardDAV/IAddressBook.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CardDAV/IAddressBook.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CardDAV/IAddressBook.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CardDAV/ICard.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CardDAV/ICard.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CardDAV/ICard.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CardDAV/ICard.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CardDAV/IDirectory.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CardDAV/IDirectory.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CardDAV/IDirectory.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CardDAV/IDirectory.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CardDAV/Plugin.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CardDAV/Plugin.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CardDAV/Plugin.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CardDAV/Plugin.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CardDAV/Property/SupportedAddressData.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CardDAV/Property/SupportedAddressData.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CardDAV/Property/SupportedAddressData.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CardDAV/Property/SupportedAddressData.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CardDAV/UserAddressBooks.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CardDAV/UserAddressBooks.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CardDAV/UserAddressBooks.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CardDAV/UserAddressBooks.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CardDAV/VCFExportPlugin.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CardDAV/VCFExportPlugin.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CardDAV/VCFExportPlugin.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CardDAV/VCFExportPlugin.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CardDAV/Version.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CardDAV/Version.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/CardDAV/Version.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/CardDAV/Version.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Auth/Backend/AbstractBasic.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Auth/Backend/AbstractBasic.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Auth/Backend/AbstractBasic.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Auth/Backend/AbstractBasic.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Auth/Backend/AbstractDigest.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Auth/Backend/AbstractDigest.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Auth/Backend/AbstractDigest.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Auth/Backend/AbstractDigest.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Auth/Backend/Apache.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Auth/Backend/Apache.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Auth/Backend/Apache.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Auth/Backend/Apache.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Auth/Backend/BackendInterface.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Auth/Backend/BackendInterface.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Auth/Backend/BackendInterface.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Auth/Backend/BackendInterface.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Auth/Backend/File.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Auth/Backend/File.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Auth/Backend/File.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Auth/Backend/File.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Auth/Backend/PDO.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Auth/Backend/PDO.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Auth/Backend/PDO.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Auth/Backend/PDO.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Auth/Plugin.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Auth/Plugin.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Auth/Plugin.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Auth/Plugin.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Browser/GuessContentType.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Browser/GuessContentType.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Browser/GuessContentType.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Browser/GuessContentType.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Browser/MapGetToPropFind.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Browser/MapGetToPropFind.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Browser/MapGetToPropFind.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Browser/MapGetToPropFind.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Browser/Plugin.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Browser/Plugin.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Browser/Plugin.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Browser/Plugin.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Browser/assets/favicon.ico b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Browser/assets/favicon.ico similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Browser/assets/favicon.ico rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Browser/assets/favicon.ico diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Browser/assets/icons/addressbook.png b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Browser/assets/icons/addressbook.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Browser/assets/icons/addressbook.png rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Browser/assets/icons/addressbook.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Browser/assets/icons/calendar.png b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Browser/assets/icons/calendar.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Browser/assets/icons/calendar.png rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Browser/assets/icons/calendar.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Browser/assets/icons/card.png b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Browser/assets/icons/card.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Browser/assets/icons/card.png rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Browser/assets/icons/card.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Browser/assets/icons/collection.png b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Browser/assets/icons/collection.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Browser/assets/icons/collection.png rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Browser/assets/icons/collection.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Browser/assets/icons/file.png b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Browser/assets/icons/file.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Browser/assets/icons/file.png rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Browser/assets/icons/file.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Browser/assets/icons/parent.png b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Browser/assets/icons/parent.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Browser/assets/icons/parent.png rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Browser/assets/icons/parent.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Browser/assets/icons/principal.png b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Browser/assets/icons/principal.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Browser/assets/icons/principal.png rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Browser/assets/icons/principal.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Client.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Client.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Client.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Client.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Collection.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Collection.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Collection.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Collection.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/BadRequest.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/BadRequest.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/BadRequest.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/BadRequest.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/Conflict.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/Conflict.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/Conflict.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/Conflict.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/ConflictingLock.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/ConflictingLock.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/ConflictingLock.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/ConflictingLock.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/FileNotFound.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/FileNotFound.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/FileNotFound.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/FileNotFound.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/Forbidden.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/Forbidden.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/Forbidden.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/Forbidden.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/InsufficientStorage.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/InsufficientStorage.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/InsufficientStorage.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/InsufficientStorage.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/InvalidResourceType.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/InvalidResourceType.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/InvalidResourceType.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/InvalidResourceType.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/LockTokenMatchesRequestUri.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/LockTokenMatchesRequestUri.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/LockTokenMatchesRequestUri.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/LockTokenMatchesRequestUri.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/Locked.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/Locked.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/Locked.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/Locked.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/MethodNotAllowed.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/MethodNotAllowed.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/MethodNotAllowed.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/MethodNotAllowed.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/NotAuthenticated.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/NotAuthenticated.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/NotAuthenticated.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/NotAuthenticated.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/NotFound.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/NotFound.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/NotFound.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/NotFound.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/NotImplemented.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/NotImplemented.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/NotImplemented.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/NotImplemented.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/PaymentRequired.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/PaymentRequired.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/PaymentRequired.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/PaymentRequired.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/PreconditionFailed.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/PreconditionFailed.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/PreconditionFailed.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/PreconditionFailed.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/ReportNotSupported.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/ReportNotSupported.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/ReportNotSupported.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/ReportNotSupported.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/RequestedRangeNotSatisfiable.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/RequestedRangeNotSatisfiable.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/RequestedRangeNotSatisfiable.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/RequestedRangeNotSatisfiable.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/ServiceUnavailable.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/ServiceUnavailable.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/ServiceUnavailable.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/ServiceUnavailable.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/UnsupportedMediaType.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/UnsupportedMediaType.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Exception/UnsupportedMediaType.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Exception/UnsupportedMediaType.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/FS/Directory.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/FS/Directory.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/FS/Directory.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/FS/Directory.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/FS/File.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/FS/File.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/FS/File.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/FS/File.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/FS/Node.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/FS/Node.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/FS/Node.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/FS/Node.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/FSExt/Directory.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/FSExt/Directory.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/FSExt/Directory.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/FSExt/Directory.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/FSExt/File.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/FSExt/File.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/FSExt/File.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/FSExt/File.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/FSExt/Node.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/FSExt/Node.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/FSExt/Node.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/FSExt/Node.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/File.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/File.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/File.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/File.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/ICollection.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/ICollection.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/ICollection.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/ICollection.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/IExtendedCollection.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/IExtendedCollection.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/IExtendedCollection.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/IExtendedCollection.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/IFile.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/IFile.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/IFile.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/IFile.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/INode.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/INode.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/INode.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/INode.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/IProperties.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/IProperties.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/IProperties.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/IProperties.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/IQuota.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/IQuota.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/IQuota.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/IQuota.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Locks/Backend/AbstractBackend.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Locks/Backend/AbstractBackend.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Locks/Backend/AbstractBackend.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Locks/Backend/AbstractBackend.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Locks/Backend/BackendInterface.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Locks/Backend/BackendInterface.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Locks/Backend/BackendInterface.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Locks/Backend/BackendInterface.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Locks/Backend/FS.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Locks/Backend/FS.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Locks/Backend/FS.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Locks/Backend/FS.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Locks/Backend/File.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Locks/Backend/File.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Locks/Backend/File.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Locks/Backend/File.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Locks/Backend/PDO.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Locks/Backend/PDO.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Locks/Backend/PDO.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Locks/Backend/PDO.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Locks/LockInfo.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Locks/LockInfo.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Locks/LockInfo.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Locks/LockInfo.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Locks/Plugin.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Locks/Plugin.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Locks/Plugin.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Locks/Plugin.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Mount/Plugin.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Mount/Plugin.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Mount/Plugin.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Mount/Plugin.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Node.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Node.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Node.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Node.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/ObjectTree.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/ObjectTree.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/ObjectTree.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/ObjectTree.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/PartialUpdate/IFile.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/PartialUpdate/IFile.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/PartialUpdate/IFile.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/PartialUpdate/IFile.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/PartialUpdate/Plugin.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/PartialUpdate/Plugin.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/PartialUpdate/Plugin.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/PartialUpdate/Plugin.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Property.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Property.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Property.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Property.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Property/GetLastModified.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Property/GetLastModified.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Property/GetLastModified.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Property/GetLastModified.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Property/Href.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Property/Href.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Property/Href.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Property/Href.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Property/HrefList.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Property/HrefList.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Property/HrefList.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Property/HrefList.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Property/IHref.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Property/IHref.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Property/IHref.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Property/IHref.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Property/LockDiscovery.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Property/LockDiscovery.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Property/LockDiscovery.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Property/LockDiscovery.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Property/ResourceType.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Property/ResourceType.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Property/ResourceType.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Property/ResourceType.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Property/Response.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Property/Response.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Property/Response.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Property/Response.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Property/ResponseList.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Property/ResponseList.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Property/ResponseList.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Property/ResponseList.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Property/SupportedLock.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Property/SupportedLock.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Property/SupportedLock.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Property/SupportedLock.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Property/SupportedReportSet.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Property/SupportedReportSet.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Property/SupportedReportSet.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Property/SupportedReportSet.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/PropertyInterface.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/PropertyInterface.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/PropertyInterface.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/PropertyInterface.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Server.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Server.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Server.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Server.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/ServerPlugin.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/ServerPlugin.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/ServerPlugin.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/ServerPlugin.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/SimpleCollection.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/SimpleCollection.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/SimpleCollection.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/SimpleCollection.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/SimpleFile.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/SimpleFile.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/SimpleFile.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/SimpleFile.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/StringUtil.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/StringUtil.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/StringUtil.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/StringUtil.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/TemporaryFileFilterPlugin.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/TemporaryFileFilterPlugin.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/TemporaryFileFilterPlugin.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/TemporaryFileFilterPlugin.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Tree.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Tree.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Tree.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Tree.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Tree/Filesystem.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Tree/Filesystem.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Tree/Filesystem.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Tree/Filesystem.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/URLUtil.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/URLUtil.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/URLUtil.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/URLUtil.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/UUIDUtil.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/UUIDUtil.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/UUIDUtil.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/UUIDUtil.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Version.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Version.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/Version.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/Version.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/XMLUtil.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/XMLUtil.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAV/XMLUtil.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAV/XMLUtil.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/AbstractPrincipalCollection.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/AbstractPrincipalCollection.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/AbstractPrincipalCollection.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/AbstractPrincipalCollection.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/Exception/AceConflict.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/Exception/AceConflict.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/Exception/AceConflict.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/Exception/AceConflict.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/Exception/NeedPrivileges.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/Exception/NeedPrivileges.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/Exception/NeedPrivileges.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/Exception/NeedPrivileges.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/Exception/NoAbstract.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/Exception/NoAbstract.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/Exception/NoAbstract.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/Exception/NoAbstract.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/Exception/NotRecognizedPrincipal.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/Exception/NotRecognizedPrincipal.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/Exception/NotRecognizedPrincipal.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/Exception/NotRecognizedPrincipal.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/Exception/NotSupportedPrivilege.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/Exception/NotSupportedPrivilege.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/Exception/NotSupportedPrivilege.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/Exception/NotSupportedPrivilege.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/IACL.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/IACL.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/IACL.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/IACL.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/IPrincipal.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/IPrincipal.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/IPrincipal.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/IPrincipal.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/IPrincipalCollection.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/IPrincipalCollection.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/IPrincipalCollection.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/IPrincipalCollection.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/Plugin.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/Plugin.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/Plugin.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/Plugin.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/Principal.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/Principal.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/Principal.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/Principal.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/PrincipalBackend/AbstractBackend.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/PrincipalBackend/AbstractBackend.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/PrincipalBackend/AbstractBackend.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/PrincipalBackend/AbstractBackend.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/PrincipalBackend/BackendInterface.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/PrincipalBackend/BackendInterface.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/PrincipalBackend/BackendInterface.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/PrincipalBackend/BackendInterface.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/PrincipalBackend/PDO.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/PrincipalBackend/PDO.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/PrincipalBackend/PDO.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/PrincipalBackend/PDO.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/PrincipalCollection.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/PrincipalCollection.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/PrincipalCollection.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/PrincipalCollection.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/Property/Acl.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/Property/Acl.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/Property/Acl.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/Property/Acl.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/Property/AclRestrictions.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/Property/AclRestrictions.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/Property/AclRestrictions.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/Property/AclRestrictions.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/Property/CurrentUserPrivilegeSet.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/Property/CurrentUserPrivilegeSet.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/Property/CurrentUserPrivilegeSet.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/Property/CurrentUserPrivilegeSet.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/Property/Principal.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/Property/Principal.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/Property/Principal.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/Property/Principal.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/Property/SupportedPrivilegeSet.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/Property/SupportedPrivilegeSet.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/Property/SupportedPrivilegeSet.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/Property/SupportedPrivilegeSet.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/Version.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/Version.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/DAVACL/Version.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/DAVACL/Version.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/HTTP/AWSAuth.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/HTTP/AWSAuth.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/HTTP/AWSAuth.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/HTTP/AWSAuth.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/HTTP/AbstractAuth.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/HTTP/AbstractAuth.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/HTTP/AbstractAuth.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/HTTP/AbstractAuth.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/HTTP/BasicAuth.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/HTTP/BasicAuth.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/HTTP/BasicAuth.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/HTTP/BasicAuth.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/HTTP/DigestAuth.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/HTTP/DigestAuth.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/HTTP/DigestAuth.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/HTTP/DigestAuth.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/HTTP/Request.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/HTTP/Request.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/HTTP/Request.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/HTTP/Request.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/HTTP/Response.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/HTTP/Response.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/HTTP/Response.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/HTTP/Response.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/HTTP/Util.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/HTTP/Util.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/HTTP/Util.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/HTTP/Util.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/HTTP/Version.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/HTTP/Version.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/HTTP/Version.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/HTTP/Version.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Cli.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Cli.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Cli.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Cli.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Component.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Component.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Component.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Component.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Component/VAlarm.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Component/VAlarm.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Component/VAlarm.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Component/VAlarm.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Component/VCalendar.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Component/VCalendar.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Component/VCalendar.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Component/VCalendar.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Component/VCard.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Component/VCard.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Component/VCard.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Component/VCard.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Component/VEvent.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Component/VEvent.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Component/VEvent.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Component/VEvent.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Component/VFreeBusy.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Component/VFreeBusy.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Component/VFreeBusy.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Component/VFreeBusy.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Component/VJournal.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Component/VJournal.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Component/VJournal.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Component/VJournal.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Component/VTodo.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Component/VTodo.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Component/VTodo.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Component/VTodo.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/DateTimeParser.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/DateTimeParser.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/DateTimeParser.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/DateTimeParser.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Document.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Document.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Document.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Document.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/ElementList.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/ElementList.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/ElementList.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/ElementList.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/EofException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/EofException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/EofException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/EofException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/FreeBusyGenerator.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/FreeBusyGenerator.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/FreeBusyGenerator.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/FreeBusyGenerator.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Node.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Node.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Node.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Node.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Parameter.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Parameter.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Parameter.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Parameter.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/ParseException.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/ParseException.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/ParseException.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/ParseException.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Parser/Json.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Parser/Json.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Parser/Json.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Parser/Json.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Parser/MimeDir.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Parser/MimeDir.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Parser/MimeDir.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Parser/MimeDir.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Parser/Parser.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Parser/Parser.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Parser/Parser.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Parser/Parser.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/Binary.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/Binary.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/Binary.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/Binary.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/Boolean.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/Boolean.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/Boolean.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/Boolean.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/FlatText.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/FlatText.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/FlatText.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/FlatText.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/Float.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/Float.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/Float.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/Float.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/ICalendar/CalAddress.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/ICalendar/CalAddress.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/ICalendar/CalAddress.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/ICalendar/CalAddress.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/ICalendar/Date.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/ICalendar/Date.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/ICalendar/Date.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/ICalendar/Date.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/ICalendar/DateTime.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/ICalendar/DateTime.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/ICalendar/DateTime.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/ICalendar/DateTime.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/ICalendar/Duration.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/ICalendar/Duration.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/ICalendar/Duration.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/ICalendar/Duration.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/ICalendar/Period.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/ICalendar/Period.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/ICalendar/Period.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/ICalendar/Period.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/ICalendar/Recur.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/ICalendar/Recur.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/ICalendar/Recur.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/ICalendar/Recur.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/Integer.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/Integer.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/Integer.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/Integer.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/Text.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/Text.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/Text.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/Text.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/Time.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/Time.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/Time.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/Time.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/Unknown.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/Unknown.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/Unknown.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/Unknown.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/Uri.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/Uri.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/Uri.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/Uri.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/UtcOffset.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/UtcOffset.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/UtcOffset.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/UtcOffset.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/VCard/Date.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/VCard/Date.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/VCard/Date.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/VCard/Date.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/VCard/DateAndOrTime.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/VCard/DateAndOrTime.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/VCard/DateAndOrTime.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/VCard/DateAndOrTime.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/VCard/DateTime.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/VCard/DateTime.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/VCard/DateTime.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/VCard/DateTime.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/VCard/LanguageTag.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/VCard/LanguageTag.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/VCard/LanguageTag.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/VCard/LanguageTag.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/VCard/TimeStamp.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/VCard/TimeStamp.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Property/VCard/TimeStamp.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Property/VCard/TimeStamp.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Reader.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Reader.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Reader.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Reader.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/RecurrenceIterator.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/RecurrenceIterator.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/RecurrenceIterator.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/RecurrenceIterator.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Splitter/ICalendar.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Splitter/ICalendar.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Splitter/ICalendar.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Splitter/ICalendar.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Splitter/SplitterInterface.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Splitter/SplitterInterface.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Splitter/SplitterInterface.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Splitter/SplitterInterface.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Splitter/VCard.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Splitter/VCard.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Splitter/VCard.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Splitter/VCard.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/StringUtil.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/StringUtil.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/StringUtil.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/StringUtil.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/TimeZoneUtil.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/TimeZoneUtil.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/TimeZoneUtil.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/TimeZoneUtil.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/VCardConverter.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/VCardConverter.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/VCardConverter.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/VCardConverter.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Version.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Version.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/Version.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/Version.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/includes.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/includes.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/SabreForRainLoop/VObject/includes.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/SabreForRainLoop/VObject/includes.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/lessphp/LICENSE b/rainloop/app/rainloop/v/1.12.1/app/libraries/lessphp/LICENSE similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/lessphp/LICENSE rename to rainloop/app/rainloop/v/1.12.1/app/libraries/lessphp/LICENSE diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/lessphp/README.md b/rainloop/app/rainloop/v/1.12.1/app/libraries/lessphp/README.md similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/lessphp/README.md rename to rainloop/app/rainloop/v/1.12.1/app/libraries/lessphp/README.md diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/lessphp/ctype.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/lessphp/ctype.php similarity index 93% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/lessphp/ctype.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/lessphp/ctype.php index 74a12d147d80ce5178fa69d311a9574b7480d23c..d2bc9a0a8bea722aa878b2f2487490abd7977c9f 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/lessphp/ctype.php +++ b/rainloop/app/rainloop/v/1.12.1/app/libraries/lessphp/ctype.php @@ -1,40 +1,40 @@ - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/pclzip/pclzip.lib.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/pclzip/pclzip.lib.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/pclzip/pclzip.lib.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/pclzip/pclzip.lib.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/pclzip/readme.txt b/rainloop/app/rainloop/v/1.12.1/app/libraries/pclzip/readme.txt similarity index 98% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/pclzip/readme.txt rename to rainloop/app/rainloop/v/1.12.1/app/libraries/pclzip/readme.txt index 6ed883947721913102281cbe9815eea3ad9ef539..d1b11e25897f11cbb3f0adf3b342bd42151bdede 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/libraries/pclzip/readme.txt +++ b/rainloop/app/rainloop/v/1.12.1/app/libraries/pclzip/readme.txt @@ -1,421 +1,421 @@ -// -------------------------------------------------------------------------------- -// PclZip 2.8.2 - readme.txt -// -------------------------------------------------------------------------------- -// License GNU/LGPL - August 2009 -// Vincent Blavet - vincent@phpconcept.net -// http://www.phpconcept.net -// -------------------------------------------------------------------------------- -// $Id: readme.txt,v 1.60 2009/09/30 20:35:21 vblavet Exp $ -// -------------------------------------------------------------------------------- - - - -0 - Sommaire -============ - 1 - Introduction - 2 - What's new - 3 - Corrected bugs - 4 - Known bugs or limitations - 5 - License - 6 - Warning - 7 - Documentation - 8 - Author - 9 - Contribute - -1 - Introduction -================ - - PclZip is a library that allow you to manage a Zip archive. - - Full documentation about PclZip can be found here : http://www.phpconcept.net/pclzip - -2 - What's new -============== - - Version 2.8.2 : - - PCLZIP_CB_PRE_EXTRACT and PCLZIP_CB_POST_EXTRACT are now supported with - extraction as a string (PCLZIP_OPT_EXTRACT_AS_STRING). The string - can also be modified in the post-extract call back. - **Bugs correction : - - PCLZIP_OPT_REMOVE_ALL_PATH was not working correctly - - Remove use of eval() and do direct call to callback functions - - Correct support of 64bits systems (Thanks to WordPress team) - - Version 2.8.1 : - - Move option PCLZIP_OPT_BY_EREG to PCLZIP_OPT_BY_PREG because ereg() is - deprecated in PHP 5.3. When using option PCLZIP_OPT_BY_EREG, PclZip will - automatically replace it by PCLZIP_OPT_BY_PREG. - - Version 2.8 : - - Improve extraction of zip archive for large files by using temporary files - This feature is working like the one defined in r2.7. - Options are renamed : PCLZIP_OPT_TEMP_FILE_ON, PCLZIP_OPT_TEMP_FILE_OFF, - PCLZIP_OPT_TEMP_FILE_THRESHOLD - - Add a ratio constant PCLZIP_TEMPORARY_FILE_RATIO to configure the auto - sense of temporary file use. - - Bug correction : Reduce filepath in returned file list to remove ennoying - './/' preambule in file path. - - Version 2.7 : - - Improve creation of zip archive for large files : - PclZip will now autosense the configured memory and use temporary files - when large file is suspected. - This feature can also ne triggered by manual options in create() and add() - methods. 'PCLZIP_OPT_ADD_TEMP_FILE_ON' force the use of temporary files, - 'PCLZIP_OPT_ADD_TEMP_FILE_OFF' disable the autosense technic, - 'PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD' allow for configuration of a size - threshold to use temporary files. - Using "temporary files" rather than "memory" might take more time, but - might give the ability to zip very large files : - Tested on my win laptop with a 88Mo file : - Zip "in-memory" : 18sec (max_execution_time=30, memory_limit=180Mo) - Zip "tmporary-files" : 23sec (max_execution_time=30, memory_limit=30Mo) - - Replace use of mktime() by time() to limit the E_STRICT error messages. - - Bug correction : When adding files with full windows path (drive letter) - PclZip is now working. Before, if the drive letter is not the default - path, PclZip was not able to add the file. - - Version 2.6 : - - Code optimisation - - New attributes PCLZIP_ATT_FILE_COMMENT gives the ability to - add a comment for a specific file. (Don't really know if this is usefull) - - New attribute PCLZIP_ATT_FILE_CONTENT gives the ability to add a string - as a file. - - New attribute PCLZIP_ATT_FILE_MTIME modify the timestamp associated with - a file. - - Correct a bug. Files archived with a timestamp with 0h0m0s were extracted - with current time - - Add CRC value in the informations returned back for each file after an - action. - - Add missing closedir() statement. - - When adding a folder, and removing the path of this folder, files were - incorrectly added with a '/' at the beginning. Which means files are - related to root in unix systems. Corrected. - - Add conditional if before constant definition. This will allow users - to redefine constants without changing the file, and then improve - upgrade of pclzip code for new versions. - - Version 2.5 : - - Introduce the ability to add file/folder with individual properties (file descriptor). - This gives for example the ability to change the filename of a zipped file. - . Able to add files individually - . Able to change full name - . Able to change short name - . Compatible with global options - - New attributes : PCLZIP_ATT_FILE_NAME, PCLZIP_ATT_FILE_NEW_SHORT_NAME, PCLZIP_ATT_FILE_NEW_FULL_NAME - - New error code : PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE - - Add a security control feature. PclZip can extract any file in any folder - of a system. People may use this to upload a zip file and try to override - a system file. The PCLZIP_OPT_EXTRACT_DIR_RESTRICTION will give the - ability to forgive any directory transversal behavior. - - New PCLZIP_OPT_EXTRACT_DIR_RESTRICTION : check extraction path - - New error code : PCLZIP_ERR_DIRECTORY_RESTRICTION - - Modification in PclZipUtilPathInclusion() : dir and path beginning with ./ will be prepend - by current path (getcwd()) - - Version 2.4 : - - Code improvment : try to speed up the code by removing unusefull call to pack() - - Correct bug in delete() : delete() should be called with no argument. This was not - the case in 2.3. This is corrected in 2.4. - - Correct a bug in path_inclusion function. When the path has several '../../', the - result was bad. - - Add a check for magic_quotes_runtime configuration. If enabled, PclZip will - disable it while working and det it back to its original value. - This resolve a lots of bad formated archive errors. - - Bug correction : PclZip now correctly unzip file in some specific situation, - when compressed content has same size as uncompressed content. - - Bug correction : When selecting option 'PCLZIP_OPT_REMOVE_ALL_PATH', - directories are not any more created. - - Code improvment : correct unclosed opendir(), better handling of . and .. in - loops. - - - Version 2.3 : - - Correct a bug with PHP5 : affecting the value 0xFE49FFE0 to a variable does not - give the same result in PHP4 and PHP5 .... - - Version 2.2 : - - Try development of PCLZIP_OPT_CRYPT ..... - However this becomes to a stop. To crypt/decrypt I need to multiply 2 long integers, - the result (greater than a long) is not supported by PHP. Even the use of bcmath - functions does not help. I did not find yet a solution ...; - - Add missing '/' at end of directory entries - - Check is a file is encrypted or not. Returns status 'unsupported_encryption' and/or - error code PCLZIP_ERR_UNSUPPORTED_ENCRYPTION. - - Corrected : Bad "version need to extract" field in local file header - - Add private method privCheckFileHeaders() in order to check local and central - file headers. PclZip is now supporting purpose bit flag bit 3. Purpose bit flag bit 3 gives - the ability to have a local file header without size, compressed size and crc filled. - - Add a generic status 'error' for file status - - Add control of compression type. PclZip only support deflate compression method. - Before v2.2, PclZip does not check the compression method used in an archive while - extracting. With v2.2 PclZip returns a new error status for a file using an unsupported - compression method. New status is "unsupported_compression". New error code is - PCLZIP_ERR_UNSUPPORTED_COMPRESSION. - - Add optional attribute PCLZIP_OPT_STOP_ON_ERROR. This will stop the extract of files - when errors like 'a folder with same name exists' or 'a newer file exists' or - 'a write protected file' exists, rather than set a status for the concerning file - and resume the extract of the zip. - - Add optional attribute PCLZIP_OPT_REPLACE_NEWER. This will force, during an extract' the - replacement of the file, even if a newer version of the file exists. - Note that today if a file with the same name already exists but is older it will be - replaced by the extracted one. - - Improve PclZipUtilOption() - - Support of zip archive with trailing bytes. Before 2.2, PclZip checks that the central - directory structure is the last data in the archive. Crypt encryption/decryption of - zip archive put trailing 0 bytes after decryption. PclZip is now supporting this. - - Version 2.1 : - - Add the ability to abort the extraction by using a user callback function. - The user can now return the value '2' in its callback which indicates to stop the - extraction. For a pre call-back extract is stopped before the extration of the current - file. For a post call back, the extraction is stopped after. - - Add the ability to extract a file (or several files) directly in the standard output. - This is done by the new parameter PCLZIP_OPT_EXTRACT_IN_OUTPUT with method extract(). - - Add support for parameters PCLZIP_OPT_COMMENT, PCLZIP_OPT_ADD_COMMENT, - PCLZIP_OPT_PREPEND_COMMENT. This will create, replace, add, or prepend comments - in the zip archive. - - When merging two archives, the comments are not any more lost, but merged, with a - blank space separator. - - Corrected bug : Files are not deleted when all files are asked to be deleted. - - Corrected bug : Folders with name '0' made PclZip to abort the create or add feature. - - - Version 2.0 : - ***** Warning : Some new features may break the backward compatibility for your scripts. - Please carefully read the readme file. - - Add the ability to delete by Index, name and regular expression. This feature is - performed by the method delete(), which uses the optional parameters - PCLZIP_OPT_BY_INDEX, PCLZIP_OPT_BY_NAME, PCLZIP_OPT_BY_EREG or PCLZIP_OPT_BY_PREG. - - Add the ability to extract by regular expression. To extract by regexp you must use the method - extract(), with the option PCLZIP_OPT_BY_EREG or PCLZIP_OPT_BY_PREG - (depending if you want to use ereg() or preg_match() syntax) followed by the - regular expression pattern. - - Add the ability to extract by index, directly with the extract() method. This is a - code improvment of the extractByIndex() method. - - Add the ability to extract by name. To extract by name you must use the method - extract(), with the option PCLZIP_OPT_BY_NAME followed by the filename to - extract or an array of filenames to extract. To extract all a folder, use the folder - name rather than the filename with a '/' at the end. - - Add the ability to add files without compression. This is done with a new attribute - which is PCLZIP_OPT_NO_COMPRESSION. - - Add the attribute PCLZIP_OPT_EXTRACT_AS_STRING, which allow to extract a file directly - in a string without using any file (or temporary file). - - Add constant PCLZIP_SEPARATOR for static configuration of filename separators in a single string. - The default separator is now a comma (,) and not any more a blank space. - THIS BREAK THE BACKWARD COMPATIBILITY : Please check if this may have an impact with - your script. - - Improve algorythm performance by removing the use of temporary files when adding or - extracting files in an archive. - - Add (correct) detection of empty filename zipping. This can occurs when the removed - path is the same - as a zipped dir. The dir is not zipped (['status'] = filtered), only its content. - - Add better support for windows paths (thanks for help from manus@manusfreedom.com). - - Corrected bug : When the archive file already exists with size=0, the add() method - fails. Corrected in 2.0. - - Remove the use of OS_WINDOWS constant. Use php_uname() function rather. - - Control the order of index ranges in extract by index feature. - - Change the internal management of folders (better handling of internal flag). - - - Version 1.3 : - - Removing the double include check. This is now done by include_once() and require_once() - PHP directives. - - Changing the error handling mecanism : Remove the use of an external error library. - The former PclError...() functions are replaced by internal equivalent methods. - By changing the environment variable PCLZIP_ERROR_EXTERNAL you can still use the former library. - Introducing the use of constants for error codes rather than integer values. This will help - in futur improvment. - Introduction of error handling functions like errorCode(), errorName() and errorInfo(). - - Remove the deprecated use of calling function with arguments passed by reference. - - Add the calling of extract(), extractByIndex(), create() and add() functions - with variable options rather than fixed arguments. - - Add the ability to remove all the file path while extracting or adding, - without any need to specify the path to remove. - This is available for extract(), extractByIndex(), create() and add() functionS by using - the new variable options parameters : - - PCLZIP_OPT_REMOVE_ALL_PATH : by indicating this option while calling the fct. - - Ability to change the mode of a file after the extraction (chmod()). - This is available for extract() and extractByIndex() functionS by using - the new variable options parameters. - - PCLZIP_OPT_SET_CHMOD : by setting the value of this option. - - Ability to definition call-back options. These call-back will be called during the adding, - or the extracting of file (extract(), extractByIndex(), create() and add() functions) : - - PCLZIP_CB_PRE_EXTRACT : will be called before each extraction of a file. The user - can trigerred the change the filename of the extracted file. The user can triggered the - skip of the extraction. This is adding a 'skipped' status in the file list result value. - - PCLZIP_CB_POST_EXTRACT : will be called after each extraction of a file. - Nothing can be triggered from that point. - - PCLZIP_CB_PRE_ADD : will be called before each add of a file. The user - can trigerred the change the stored filename of the added file. The user can triggered the - skip of the add. This is adding a 'skipped' status in the file list result value. - - PCLZIP_CB_POST_ADD : will be called after each add of a file. - Nothing can be triggered from that point. - - Two status are added in the file list returned as function result : skipped & filename_too_long - 'skipped' is used when a call-back function ask for skipping the file. - 'filename_too_long' is used while adding a file with a too long filename to archive (the file is - not added) - - Adding the function PclZipUtilPathInclusion(), that check the inclusion of a path into - a directory. - - Add a check of the presence of the archive file before some actions (like list, ...) - - Add the initialisation of field "index" in header array. This means that by - default index will be -1 when not explicitly set by the methods. - - Version 1.2 : - - Adding a duplicate function. - - Adding a merge function. The merge function is a "quick merge" function, - it just append the content of an archive at the end of the first one. There - is no check for duplicate files or more recent files. - - Improve the search of the central directory end. - - Version 1.1.2 : - - - Changing the license of PclZip. PclZip is now released under the GNU / LGPL license - (see License section). - - Adding the optional support of a static temporary directory. You will need to configure - the constant PCLZIP_TEMPORARY_DIR if you want to use this feature. - - Improving the rename() function. In some cases rename() does not work (different - Filesystems), so it will be replaced by a copy() + unlink() functions. - - Version 1.1.1 : - - - Maintenance release, no new feature. - - Version 1.1 : - - - New method Add() : adding files in the archive - - New method ExtractByIndex() : partial extract of the archive, files are identified by - their index in the archive - - New method DeleteByIndex() : delete some files/folder entries from the archive, - files are identified by their index in the archive. - - Adding a test of the zlib extension presence. If not present abort the script. - - Version 1.0.1 : - - - No new feature - - -3 - Corrected bugs -================== - - Corrected in Version 2.0 : - - Corrected : During an extraction, if a call-back fucntion is used and try to skip - a file, all the extraction process is stopped. - - Corrected in Version 1.3 : - - Corrected : Support of static synopsis for method extract() is broken. - - Corrected : invalid size of archive content field (0xFF) should be (0xFFFF). - - Corrected : When an extract is done with a remove_path parameter, the entry for - the directory with exactly the same path is not skipped/filtered. - - Corrected : extractByIndex() and deleteByIndex() were not managing index in the - right way. For example indexes '1,3-5,11' will only extract files 1 and 11. This - is due to a sort of the index resulting table that puts 11 before 3-5 (sort on - string and not interger). The sort is temporarilly removed, this means that - you must provide a sorted list of index ranges. - - Corrected in Version 1.2 : - - - Nothing. - - Corrected in Version 1.1.2 : - - - Corrected : Winzip is unable to delete or add new files in a PclZip created archives. - - Corrected in Version 1.1.1 : - - - Corrected : When archived file is not compressed (0% compression), the - extract method fails. - - Corrected in Version 1.1 : - - - Corrected : Adding a complete tree of folder may result in a bad archive - creation. - - Corrected in Version 1.0.1 : - - - Corrected : Error while compressing files greater than PCLZIP_READ_BLOCK_SIZE (default=1024). - - -4 - Known bugs or limitations -============================= - - Please publish bugs reports in SourceForge : - http://sourceforge.net/tracker/?group_id=40254&atid=427564 - - In Version 2.x : - - PclZip does only support file uncompressed or compressed with deflate (compression method 8) - - PclZip does not support password protected zip archive - - Some concern were seen when changing mtime of a file while archiving. - Seems to be linked to Daylight Saving Time (PclTest_changing_mtime). - - In Version 1.2 : - - - merge() methods does not check for duplicate files or last date of modifications. - - In Version 1.1 : - - - Limitation : Using 'extract' fields in the file header in the zip archive is not supported. - - WinZip is unable to delete a single file in a PclZip created archive. It is also unable to - add a file in a PclZip created archive. (Corrected in v.1.2) - - In Version 1.0.1 : - - - Adding a complete tree of folder may result in a bad archive - creation. (Corrected in V.1.1). - - Path given to methods must be in the unix format (/) and not the Windows format (\). - Workaround : Use only / directory separators. - - PclZip is using temporary files that are sometime the name of the file with a .tmp or .gz - added suffix. Files with these names may already exist and may be overwritten. - Workaround : none. - - PclZip does not check if the zlib extension is present. If it is absent, the zip - file is not created and the lib abort without warning. - Workaround : enable the zlib extension on the php install - - In Version 1.0 : - - - Error while compressing files greater than PCLZIP_READ_BLOCK_SIZE (default=1024). - (Corrected in v.1.0.1) - - Limitation : Multi-disk zip archive are not supported. - - -5 - License -=========== - - Since version 1.1.2, PclZip Library is released under GNU/LGPL license. - This library is free, so you can use it at no cost. - - HOWEVER, if you release a script, an application, a library or any kind of - code using PclZip library (or a part of it), YOU MUST : - - Indicate in the documentation (or a readme file), that your work - uses PclZip Library, and make a reference to the author and the web site - http://www.phpconcept.net - - Gives the ability to the final user to update the PclZip libary. - - I will also appreciate that you send me a mail (vincent@phpconcept.net), just to - be aware that someone is using PclZip. - - For more information about GNU/LGPL license : http://www.gnu.org - -6 - Warning -================= - - This library and the associated files are non commercial, non professional work. - It should not have unexpected results. However if any damage is caused by this software - the author can not be responsible. - The use of this software is at the risk of the user. - -7 - Documentation -================= - PclZip User Manuel is available in English on PhpConcept : http://www.phpconcept.net/pclzip/man/en/index.php - A Russian translation was done by Feskov Kuzma : http://php.russofile.ru/ru/authors/unsort/zip/ - -8 - Author -========== - - This software was written by Vincent Blavet (vincent@phpconcept.net) on its leasure time. - -9 - Contribute -============== - If you want to contribute to the development of PclZip, please contact vincent@phpconcept.net. - If you can help in financing PhpConcept hosting service, please go to - http://www.phpconcept.net/soutien.php +// -------------------------------------------------------------------------------- +// PclZip 2.8.2 - readme.txt +// -------------------------------------------------------------------------------- +// License GNU/LGPL - August 2009 +// Vincent Blavet - vincent@phpconcept.net +// http://www.phpconcept.net +// -------------------------------------------------------------------------------- +// $Id: readme.txt,v 1.60 2009/09/30 20:35:21 vblavet Exp $ +// -------------------------------------------------------------------------------- + + + +0 - Sommaire +============ + 1 - Introduction + 2 - What's new + 3 - Corrected bugs + 4 - Known bugs or limitations + 5 - License + 6 - Warning + 7 - Documentation + 8 - Author + 9 - Contribute + +1 - Introduction +================ + + PclZip is a library that allow you to manage a Zip archive. + + Full documentation about PclZip can be found here : http://www.phpconcept.net/pclzip + +2 - What's new +============== + + Version 2.8.2 : + - PCLZIP_CB_PRE_EXTRACT and PCLZIP_CB_POST_EXTRACT are now supported with + extraction as a string (PCLZIP_OPT_EXTRACT_AS_STRING). The string + can also be modified in the post-extract call back. + **Bugs correction : + - PCLZIP_OPT_REMOVE_ALL_PATH was not working correctly + - Remove use of eval() and do direct call to callback functions + - Correct support of 64bits systems (Thanks to WordPress team) + + Version 2.8.1 : + - Move option PCLZIP_OPT_BY_EREG to PCLZIP_OPT_BY_PREG because ereg() is + deprecated in PHP 5.3. When using option PCLZIP_OPT_BY_EREG, PclZip will + automatically replace it by PCLZIP_OPT_BY_PREG. + + Version 2.8 : + - Improve extraction of zip archive for large files by using temporary files + This feature is working like the one defined in r2.7. + Options are renamed : PCLZIP_OPT_TEMP_FILE_ON, PCLZIP_OPT_TEMP_FILE_OFF, + PCLZIP_OPT_TEMP_FILE_THRESHOLD + - Add a ratio constant PCLZIP_TEMPORARY_FILE_RATIO to configure the auto + sense of temporary file use. + - Bug correction : Reduce filepath in returned file list to remove ennoying + './/' preambule in file path. + + Version 2.7 : + - Improve creation of zip archive for large files : + PclZip will now autosense the configured memory and use temporary files + when large file is suspected. + This feature can also ne triggered by manual options in create() and add() + methods. 'PCLZIP_OPT_ADD_TEMP_FILE_ON' force the use of temporary files, + 'PCLZIP_OPT_ADD_TEMP_FILE_OFF' disable the autosense technic, + 'PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD' allow for configuration of a size + threshold to use temporary files. + Using "temporary files" rather than "memory" might take more time, but + might give the ability to zip very large files : + Tested on my win laptop with a 88Mo file : + Zip "in-memory" : 18sec (max_execution_time=30, memory_limit=180Mo) + Zip "tmporary-files" : 23sec (max_execution_time=30, memory_limit=30Mo) + - Replace use of mktime() by time() to limit the E_STRICT error messages. + - Bug correction : When adding files with full windows path (drive letter) + PclZip is now working. Before, if the drive letter is not the default + path, PclZip was not able to add the file. + + Version 2.6 : + - Code optimisation + - New attributes PCLZIP_ATT_FILE_COMMENT gives the ability to + add a comment for a specific file. (Don't really know if this is usefull) + - New attribute PCLZIP_ATT_FILE_CONTENT gives the ability to add a string + as a file. + - New attribute PCLZIP_ATT_FILE_MTIME modify the timestamp associated with + a file. + - Correct a bug. Files archived with a timestamp with 0h0m0s were extracted + with current time + - Add CRC value in the informations returned back for each file after an + action. + - Add missing closedir() statement. + - When adding a folder, and removing the path of this folder, files were + incorrectly added with a '/' at the beginning. Which means files are + related to root in unix systems. Corrected. + - Add conditional if before constant definition. This will allow users + to redefine constants without changing the file, and then improve + upgrade of pclzip code for new versions. + + Version 2.5 : + - Introduce the ability to add file/folder with individual properties (file descriptor). + This gives for example the ability to change the filename of a zipped file. + . Able to add files individually + . Able to change full name + . Able to change short name + . Compatible with global options + - New attributes : PCLZIP_ATT_FILE_NAME, PCLZIP_ATT_FILE_NEW_SHORT_NAME, PCLZIP_ATT_FILE_NEW_FULL_NAME + - New error code : PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE + - Add a security control feature. PclZip can extract any file in any folder + of a system. People may use this to upload a zip file and try to override + a system file. The PCLZIP_OPT_EXTRACT_DIR_RESTRICTION will give the + ability to forgive any directory transversal behavior. + - New PCLZIP_OPT_EXTRACT_DIR_RESTRICTION : check extraction path + - New error code : PCLZIP_ERR_DIRECTORY_RESTRICTION + - Modification in PclZipUtilPathInclusion() : dir and path beginning with ./ will be prepend + by current path (getcwd()) + + Version 2.4 : + - Code improvment : try to speed up the code by removing unusefull call to pack() + - Correct bug in delete() : delete() should be called with no argument. This was not + the case in 2.3. This is corrected in 2.4. + - Correct a bug in path_inclusion function. When the path has several '../../', the + result was bad. + - Add a check for magic_quotes_runtime configuration. If enabled, PclZip will + disable it while working and det it back to its original value. + This resolve a lots of bad formated archive errors. + - Bug correction : PclZip now correctly unzip file in some specific situation, + when compressed content has same size as uncompressed content. + - Bug correction : When selecting option 'PCLZIP_OPT_REMOVE_ALL_PATH', + directories are not any more created. + - Code improvment : correct unclosed opendir(), better handling of . and .. in + loops. + + + Version 2.3 : + - Correct a bug with PHP5 : affecting the value 0xFE49FFE0 to a variable does not + give the same result in PHP4 and PHP5 .... + + Version 2.2 : + - Try development of PCLZIP_OPT_CRYPT ..... + However this becomes to a stop. To crypt/decrypt I need to multiply 2 long integers, + the result (greater than a long) is not supported by PHP. Even the use of bcmath + functions does not help. I did not find yet a solution ...; + - Add missing '/' at end of directory entries + - Check is a file is encrypted or not. Returns status 'unsupported_encryption' and/or + error code PCLZIP_ERR_UNSUPPORTED_ENCRYPTION. + - Corrected : Bad "version need to extract" field in local file header + - Add private method privCheckFileHeaders() in order to check local and central + file headers. PclZip is now supporting purpose bit flag bit 3. Purpose bit flag bit 3 gives + the ability to have a local file header without size, compressed size and crc filled. + - Add a generic status 'error' for file status + - Add control of compression type. PclZip only support deflate compression method. + Before v2.2, PclZip does not check the compression method used in an archive while + extracting. With v2.2 PclZip returns a new error status for a file using an unsupported + compression method. New status is "unsupported_compression". New error code is + PCLZIP_ERR_UNSUPPORTED_COMPRESSION. + - Add optional attribute PCLZIP_OPT_STOP_ON_ERROR. This will stop the extract of files + when errors like 'a folder with same name exists' or 'a newer file exists' or + 'a write protected file' exists, rather than set a status for the concerning file + and resume the extract of the zip. + - Add optional attribute PCLZIP_OPT_REPLACE_NEWER. This will force, during an extract' the + replacement of the file, even if a newer version of the file exists. + Note that today if a file with the same name already exists but is older it will be + replaced by the extracted one. + - Improve PclZipUtilOption() + - Support of zip archive with trailing bytes. Before 2.2, PclZip checks that the central + directory structure is the last data in the archive. Crypt encryption/decryption of + zip archive put trailing 0 bytes after decryption. PclZip is now supporting this. + + Version 2.1 : + - Add the ability to abort the extraction by using a user callback function. + The user can now return the value '2' in its callback which indicates to stop the + extraction. For a pre call-back extract is stopped before the extration of the current + file. For a post call back, the extraction is stopped after. + - Add the ability to extract a file (or several files) directly in the standard output. + This is done by the new parameter PCLZIP_OPT_EXTRACT_IN_OUTPUT with method extract(). + - Add support for parameters PCLZIP_OPT_COMMENT, PCLZIP_OPT_ADD_COMMENT, + PCLZIP_OPT_PREPEND_COMMENT. This will create, replace, add, or prepend comments + in the zip archive. + - When merging two archives, the comments are not any more lost, but merged, with a + blank space separator. + - Corrected bug : Files are not deleted when all files are asked to be deleted. + - Corrected bug : Folders with name '0' made PclZip to abort the create or add feature. + + + Version 2.0 : + ***** Warning : Some new features may break the backward compatibility for your scripts. + Please carefully read the readme file. + - Add the ability to delete by Index, name and regular expression. This feature is + performed by the method delete(), which uses the optional parameters + PCLZIP_OPT_BY_INDEX, PCLZIP_OPT_BY_NAME, PCLZIP_OPT_BY_EREG or PCLZIP_OPT_BY_PREG. + - Add the ability to extract by regular expression. To extract by regexp you must use the method + extract(), with the option PCLZIP_OPT_BY_EREG or PCLZIP_OPT_BY_PREG + (depending if you want to use ereg() or preg_match() syntax) followed by the + regular expression pattern. + - Add the ability to extract by index, directly with the extract() method. This is a + code improvment of the extractByIndex() method. + - Add the ability to extract by name. To extract by name you must use the method + extract(), with the option PCLZIP_OPT_BY_NAME followed by the filename to + extract or an array of filenames to extract. To extract all a folder, use the folder + name rather than the filename with a '/' at the end. + - Add the ability to add files without compression. This is done with a new attribute + which is PCLZIP_OPT_NO_COMPRESSION. + - Add the attribute PCLZIP_OPT_EXTRACT_AS_STRING, which allow to extract a file directly + in a string without using any file (or temporary file). + - Add constant PCLZIP_SEPARATOR for static configuration of filename separators in a single string. + The default separator is now a comma (,) and not any more a blank space. + THIS BREAK THE BACKWARD COMPATIBILITY : Please check if this may have an impact with + your script. + - Improve algorythm performance by removing the use of temporary files when adding or + extracting files in an archive. + - Add (correct) detection of empty filename zipping. This can occurs when the removed + path is the same + as a zipped dir. The dir is not zipped (['status'] = filtered), only its content. + - Add better support for windows paths (thanks for help from manus@manusfreedom.com). + - Corrected bug : When the archive file already exists with size=0, the add() method + fails. Corrected in 2.0. + - Remove the use of OS_WINDOWS constant. Use php_uname() function rather. + - Control the order of index ranges in extract by index feature. + - Change the internal management of folders (better handling of internal flag). + + + Version 1.3 : + - Removing the double include check. This is now done by include_once() and require_once() + PHP directives. + - Changing the error handling mecanism : Remove the use of an external error library. + The former PclError...() functions are replaced by internal equivalent methods. + By changing the environment variable PCLZIP_ERROR_EXTERNAL you can still use the former library. + Introducing the use of constants for error codes rather than integer values. This will help + in futur improvment. + Introduction of error handling functions like errorCode(), errorName() and errorInfo(). + - Remove the deprecated use of calling function with arguments passed by reference. + - Add the calling of extract(), extractByIndex(), create() and add() functions + with variable options rather than fixed arguments. + - Add the ability to remove all the file path while extracting or adding, + without any need to specify the path to remove. + This is available for extract(), extractByIndex(), create() and add() functionS by using + the new variable options parameters : + - PCLZIP_OPT_REMOVE_ALL_PATH : by indicating this option while calling the fct. + - Ability to change the mode of a file after the extraction (chmod()). + This is available for extract() and extractByIndex() functionS by using + the new variable options parameters. + - PCLZIP_OPT_SET_CHMOD : by setting the value of this option. + - Ability to definition call-back options. These call-back will be called during the adding, + or the extracting of file (extract(), extractByIndex(), create() and add() functions) : + - PCLZIP_CB_PRE_EXTRACT : will be called before each extraction of a file. The user + can trigerred the change the filename of the extracted file. The user can triggered the + skip of the extraction. This is adding a 'skipped' status in the file list result value. + - PCLZIP_CB_POST_EXTRACT : will be called after each extraction of a file. + Nothing can be triggered from that point. + - PCLZIP_CB_PRE_ADD : will be called before each add of a file. The user + can trigerred the change the stored filename of the added file. The user can triggered the + skip of the add. This is adding a 'skipped' status in the file list result value. + - PCLZIP_CB_POST_ADD : will be called after each add of a file. + Nothing can be triggered from that point. + - Two status are added in the file list returned as function result : skipped & filename_too_long + 'skipped' is used when a call-back function ask for skipping the file. + 'filename_too_long' is used while adding a file with a too long filename to archive (the file is + not added) + - Adding the function PclZipUtilPathInclusion(), that check the inclusion of a path into + a directory. + - Add a check of the presence of the archive file before some actions (like list, ...) + - Add the initialisation of field "index" in header array. This means that by + default index will be -1 when not explicitly set by the methods. + + Version 1.2 : + - Adding a duplicate function. + - Adding a merge function. The merge function is a "quick merge" function, + it just append the content of an archive at the end of the first one. There + is no check for duplicate files or more recent files. + - Improve the search of the central directory end. + + Version 1.1.2 : + + - Changing the license of PclZip. PclZip is now released under the GNU / LGPL license + (see License section). + - Adding the optional support of a static temporary directory. You will need to configure + the constant PCLZIP_TEMPORARY_DIR if you want to use this feature. + - Improving the rename() function. In some cases rename() does not work (different + Filesystems), so it will be replaced by a copy() + unlink() functions. + + Version 1.1.1 : + + - Maintenance release, no new feature. + + Version 1.1 : + + - New method Add() : adding files in the archive + - New method ExtractByIndex() : partial extract of the archive, files are identified by + their index in the archive + - New method DeleteByIndex() : delete some files/folder entries from the archive, + files are identified by their index in the archive. + - Adding a test of the zlib extension presence. If not present abort the script. + + Version 1.0.1 : + + - No new feature + + +3 - Corrected bugs +================== + + Corrected in Version 2.0 : + - Corrected : During an extraction, if a call-back fucntion is used and try to skip + a file, all the extraction process is stopped. + + Corrected in Version 1.3 : + - Corrected : Support of static synopsis for method extract() is broken. + - Corrected : invalid size of archive content field (0xFF) should be (0xFFFF). + - Corrected : When an extract is done with a remove_path parameter, the entry for + the directory with exactly the same path is not skipped/filtered. + - Corrected : extractByIndex() and deleteByIndex() were not managing index in the + right way. For example indexes '1,3-5,11' will only extract files 1 and 11. This + is due to a sort of the index resulting table that puts 11 before 3-5 (sort on + string and not interger). The sort is temporarilly removed, this means that + you must provide a sorted list of index ranges. + + Corrected in Version 1.2 : + + - Nothing. + + Corrected in Version 1.1.2 : + + - Corrected : Winzip is unable to delete or add new files in a PclZip created archives. + + Corrected in Version 1.1.1 : + + - Corrected : When archived file is not compressed (0% compression), the + extract method fails. + + Corrected in Version 1.1 : + + - Corrected : Adding a complete tree of folder may result in a bad archive + creation. + + Corrected in Version 1.0.1 : + + - Corrected : Error while compressing files greater than PCLZIP_READ_BLOCK_SIZE (default=1024). + + +4 - Known bugs or limitations +============================= + + Please publish bugs reports in SourceForge : + http://sourceforge.net/tracker/?group_id=40254&atid=427564 + + In Version 2.x : + - PclZip does only support file uncompressed or compressed with deflate (compression method 8) + - PclZip does not support password protected zip archive + - Some concern were seen when changing mtime of a file while archiving. + Seems to be linked to Daylight Saving Time (PclTest_changing_mtime). + + In Version 1.2 : + + - merge() methods does not check for duplicate files or last date of modifications. + + In Version 1.1 : + + - Limitation : Using 'extract' fields in the file header in the zip archive is not supported. + - WinZip is unable to delete a single file in a PclZip created archive. It is also unable to + add a file in a PclZip created archive. (Corrected in v.1.2) + + In Version 1.0.1 : + + - Adding a complete tree of folder may result in a bad archive + creation. (Corrected in V.1.1). + - Path given to methods must be in the unix format (/) and not the Windows format (\). + Workaround : Use only / directory separators. + - PclZip is using temporary files that are sometime the name of the file with a .tmp or .gz + added suffix. Files with these names may already exist and may be overwritten. + Workaround : none. + - PclZip does not check if the zlib extension is present. If it is absent, the zip + file is not created and the lib abort without warning. + Workaround : enable the zlib extension on the php install + + In Version 1.0 : + + - Error while compressing files greater than PCLZIP_READ_BLOCK_SIZE (default=1024). + (Corrected in v.1.0.1) + - Limitation : Multi-disk zip archive are not supported. + + +5 - License +=========== + + Since version 1.1.2, PclZip Library is released under GNU/LGPL license. + This library is free, so you can use it at no cost. + + HOWEVER, if you release a script, an application, a library or any kind of + code using PclZip library (or a part of it), YOU MUST : + - Indicate in the documentation (or a readme file), that your work + uses PclZip Library, and make a reference to the author and the web site + http://www.phpconcept.net + - Gives the ability to the final user to update the PclZip libary. + + I will also appreciate that you send me a mail (vincent@phpconcept.net), just to + be aware that someone is using PclZip. + + For more information about GNU/LGPL license : http://www.gnu.org + +6 - Warning +================= + + This library and the associated files are non commercial, non professional work. + It should not have unexpected results. However if any damage is caused by this software + the author can not be responsible. + The use of this software is at the risk of the user. + +7 - Documentation +================= + PclZip User Manuel is available in English on PhpConcept : http://www.phpconcept.net/pclzip/man/en/index.php + A Russian translation was done by Feskov Kuzma : http://php.russofile.ru/ru/authors/unsort/zip/ + +8 - Author +========== + + This software was written by Vincent Blavet (vincent@phpconcept.net) on its leasure time. + +9 - Contribute +============== + If you want to contribute to the development of PclZip, please contact vincent@phpconcept.net. + If you can help in financing PhpConcept hosting service, please go to + http://www.phpconcept.net/soutien.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/Crypt/AES.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/Crypt/AES.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/Crypt/AES.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/Crypt/AES.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/Crypt/Base.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/Crypt/Base.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/Crypt/Base.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/Crypt/Base.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/Crypt/Blowfish.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/Crypt/Blowfish.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/Crypt/Blowfish.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/Crypt/Blowfish.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/Crypt/DES.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/Crypt/DES.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/Crypt/DES.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/Crypt/DES.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/Crypt/Hash.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/Crypt/Hash.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/Crypt/Hash.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/Crypt/Hash.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/Crypt/RC2.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/Crypt/RC2.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/Crypt/RC2.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/Crypt/RC2.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/Crypt/RC4.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/Crypt/RC4.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/Crypt/RC4.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/Crypt/RC4.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/Crypt/RSA.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/Crypt/RSA.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/Crypt/RSA.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/Crypt/RSA.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/Crypt/Random.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/Crypt/Random.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/Crypt/Random.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/Crypt/Random.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/Crypt/Rijndael.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/Crypt/Rijndael.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/Crypt/Rijndael.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/Crypt/Rijndael.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/Crypt/TripleDES.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/Crypt/TripleDES.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/Crypt/TripleDES.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/Crypt/TripleDES.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/Crypt/Twofish.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/Crypt/Twofish.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/Crypt/Twofish.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/Crypt/Twofish.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/File/ANSI.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/File/ANSI.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/File/ANSI.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/File/ANSI.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/File/ASN1.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/File/ASN1.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/File/ASN1.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/File/ASN1.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/File/X509.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/File/X509.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/File/X509.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/File/X509.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/Math/BigInteger.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/Math/BigInteger.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/Math/BigInteger.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/Math/BigInteger.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/Net/SCP.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/Net/SCP.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/Net/SCP.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/Net/SCP.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/Net/SFTP.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/Net/SFTP.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/Net/SFTP.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/Net/SFTP.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/Net/SFTP/Stream.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/Net/SFTP/Stream.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/Net/SFTP/Stream.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/Net/SFTP/Stream.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/Net/SSH1.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/Net/SSH1.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/Net/SSH1.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/Net/SSH1.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/Net/SSH2.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/Net/SSH2.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/Net/SSH2.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/Net/SSH2.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/System/SSH/Agent.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/System/SSH/Agent.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/System/SSH/Agent.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/System/SSH/Agent.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/System/SSH_Agent.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/System/SSH_Agent.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/System/SSH_Agent.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/System/SSH_Agent.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/openssl.cnf b/rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/openssl.cnf similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/phpseclib/openssl.cnf rename to rainloop/app/rainloop/v/1.12.1/app/libraries/phpseclib/openssl.cnf diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/spyc/COPYING b/rainloop/app/rainloop/v/1.12.1/app/libraries/spyc/COPYING similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/spyc/COPYING rename to rainloop/app/rainloop/v/1.12.1/app/libraries/spyc/COPYING diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/spyc/README.md b/rainloop/app/rainloop/v/1.12.1/app/libraries/spyc/README.md similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/spyc/README.md rename to rainloop/app/rainloop/v/1.12.1/app/libraries/spyc/README.md diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/spyc/Spyc.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/spyc/Spyc.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/spyc/Spyc.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/spyc/Spyc.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/spyc/composer.json b/rainloop/app/rainloop/v/1.12.1/app/libraries/spyc/composer.json similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/spyc/composer.json rename to rainloop/app/rainloop/v/1.12.1/app/libraries/spyc/composer.json diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/tmhOAuth/LICENSE b/rainloop/app/rainloop/v/1.12.1/app/libraries/tmhOAuth/LICENSE similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/tmhOAuth/LICENSE rename to rainloop/app/rainloop/v/1.12.1/app/libraries/tmhOAuth/LICENSE diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/tmhOAuth/README.md b/rainloop/app/rainloop/v/1.12.1/app/libraries/tmhOAuth/README.md similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/tmhOAuth/README.md rename to rainloop/app/rainloop/v/1.12.1/app/libraries/tmhOAuth/README.md diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/tmhOAuth/cacert.pem b/rainloop/app/rainloop/v/1.12.1/app/libraries/tmhOAuth/cacert.pem similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/tmhOAuth/cacert.pem rename to rainloop/app/rainloop/v/1.12.1/app/libraries/tmhOAuth/cacert.pem diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/tmhOAuth/tmhOAuth.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/tmhOAuth/tmhOAuth.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/tmhOAuth/tmhOAuth.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/tmhOAuth/tmhOAuth.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/libraries/tmhOAuth/tmhUtilities.php b/rainloop/app/rainloop/v/1.12.1/app/libraries/tmhOAuth/tmhUtilities.php similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/libraries/tmhOAuth/tmhUtilities.php rename to rainloop/app/rainloop/v/1.12.1/app/libraries/tmhOAuth/tmhUtilities.php diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/README b/rainloop/app/rainloop/v/1.12.1/app/localization/README similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/README rename to rainloop/app/rainloop/v/1.12.1/app/localization/README diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/admin/README b/rainloop/app/rainloop/v/1.12.1/app/localization/admin/README similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/admin/README rename to rainloop/app/rainloop/v/1.12.1/app/localization/admin/README diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/admin/_source.en.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/admin/_source.en.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/admin/_source.en.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/admin/_source.en.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/admin/cs_CZ.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/admin/cs_CZ.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/admin/cs_CZ.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/admin/cs_CZ.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/admin/da_DK.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/admin/da_DK.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/admin/da_DK.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/admin/da_DK.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/admin/de_DE.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/admin/de_DE.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/admin/de_DE.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/admin/de_DE.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/admin/en_US.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/admin/en_US.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/admin/en_US.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/admin/en_US.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/admin/es_ES.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/admin/es_ES.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/admin/es_ES.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/admin/es_ES.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/admin/fa_IR.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/admin/fa_IR.yml similarity index 98% rename from rainloop/app/rainloop/v/1.12.0/app/localization/admin/fa_IR.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/admin/fa_IR.yml index 68f6c7a1ad49dddedb90aff815857f63faa79b26..28771b2e1667b39f468ef389a52dc1fc88966346 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/localization/admin/fa_IR.yml +++ b/rainloop/app/rainloop/v/1.12.1/app/localization/admin/fa_IR.yml @@ -26,6 +26,7 @@ fa_IR: LABEL_ALLOW_LANGUAGES_ON_SETTINGS: "زبان در صفحه تنظیمات قابل انتخاب باشد" LABEL_ALLOW_THEMES_ON_SETTINGS: "پوسته در صفحه تنظیمات قابل انتخاب باشد" LABEL_ALLOW_BACKGROUND_ON_SETTINGS: "تصویر پشت زمینه در صفحه تنظیمات قابل انتخاب باشد" + LABEL_NEW_FOLDER_MOVE: "دکمه جدید «انتقال به پوشه»" LABEL_SHOW_THUMBNAILS: "اندازه کوچک را نشان بده (پیوست‌ها)" LABEL_ALLOW_GRAVATAR: "اجازه استفاده از آواتار" LEGEND_MAIN: "اصلی" @@ -33,6 +34,7 @@ fa_IR: LABEL_ALLOW_ADDITIONAL_ACCOUNTS: "مجوز استفاده از نام‌های کاربری دیگر" LABEL_ALLOW_IDENTITIES: "اجازه استفاده از چندین شناسه" LABEL_ALLOW_TEMPLATES: "اجازه استفاده از پوسته‌ها" + ALERT_DATA_ACCESS: "شاخه data قابل دسترس هست. تنظیمات وب‌سرور را طوری انجام دهید این شاخه از بیرون قابل دسترس نباشد. اطلاعات بیشتر اینجا هست:" ALERT_WARNING: "اخطار!" HTML_ALERT_WEAK_PASSWORD: |+ شما در حال استفاده از گذرواژه پیش‌فرض کاربر مدیر هستید. diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/admin/fi_FI.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/admin/fi_FI.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/admin/fi_FI.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/admin/fi_FI.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/admin/fr_FR.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/admin/fr_FR.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/admin/fr_FR.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/admin/fr_FR.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/admin/hu_HU.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/admin/hu_HU.yml similarity index 98% rename from rainloop/app/rainloop/v/1.12.0/app/localization/admin/hu_HU.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/admin/hu_HU.yml index df08e6c54dd80cb8ae794ddd97cdc30f7453067a..822747b6d0a305bfa7ea65de49a70279985c6feb 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/localization/admin/hu_HU.yml +++ b/rainloop/app/rainloop/v/1.12.1/app/localization/admin/hu_HU.yml @@ -34,6 +34,7 @@ hu_HU: LABEL_ALLOW_ADDITIONAL_ACCOUNTS: "További fiókok engedélyezése" LABEL_ALLOW_IDENTITIES: "Több identitás engedélyezése" LABEL_ALLOW_TEMPLATES: "Sablonok engedélyezése" + ALERT_DATA_ACCESS: "A RainLoop adatmappája hozzáférhető. Kérlek állítsd be úgy a webszervert, hogy az adatmappát rejtse el a külső hozzáférés elől. További tudnivalók itt:" ALERT_WARNING: "Figyelmeztetés!" HTML_ALERT_WEAK_PASSWORD: | Az alapértelmezett admin jelszót használod diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/admin/it_IT.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/admin/it_IT.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/admin/it_IT.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/admin/it_IT.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/admin/ja_JP.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/admin/ja_JP.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/admin/ja_JP.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/admin/ja_JP.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/admin/lt_LT.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/admin/lt_LT.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/admin/lt_LT.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/admin/lt_LT.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/admin/nb_NO.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/admin/nb_NO.yml similarity index 99% rename from rainloop/app/rainloop/v/1.12.0/app/localization/admin/nb_NO.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/admin/nb_NO.yml index 1d4bf2454d1a8db4e00e81aac10595a086aafcb4..2f5fcbcadc728bf80f65f4538d2b9721a8c2f190 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/localization/admin/nb_NO.yml +++ b/rainloop/app/rainloop/v/1.12.1/app/localization/admin/nb_NO.yml @@ -34,6 +34,7 @@ nb_NO: LABEL_ALLOW_ADDITIONAL_ACCOUNTS: "Tillat bruk av flere kontoer" LABEL_ALLOW_IDENTITIES: "Tillat bruk av flere identiteter" LABEL_ALLOW_TEMPLATES: "Tillat bruk av maler" + ALERT_DATA_ACCESS: "RainLoop-datamappa di er offentlig tiljgengelig. Sett opp webtjeneren slik at den ikke viser datamappa. Les mer her:" ALERT_WARNING: "Advarsel!" HTML_ALERT_WEAK_PASSWORD: | Du bruker forvalgt admin-passord. diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/admin/nl_NL.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/admin/nl_NL.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/admin/nl_NL.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/admin/nl_NL.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/admin/pl_PL.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/admin/pl_PL.yml similarity index 64% rename from rainloop/app/rainloop/v/1.12.0/app/localization/admin/pl_PL.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/admin/pl_PL.yml index 3925ff5d774c31668b4ace2b873bdd83cce656a5..fb263596584ef6475c3b28d37eb1ef7fa1571381 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/localization/admin/pl_PL.yml +++ b/rainloop/app/rainloop/v/1.12.1/app/localization/admin/pl_PL.yml @@ -2,7 +2,7 @@ pl_PL: LOGIN: LABEL_LOGIN: "Login" LABEL_PASSWORD: "Hasło" - BUTTON_LOGIN: "Zaloguj" + BUTTON_LOGIN: "Zaloguj do panelu administracjnego" TOP_PANEL: LABEL_PREMIUM: "Premium" LABEL_ADMIN_PANEL: "Panel administracyjny" @@ -17,12 +17,12 @@ pl_PL: LABEL_PLUGINS_NAME: "Wtyczki" LABEL_PACKAGES_NAME: "Zarządzanie wtyczkami" LABEL_LICENSING_NAME: "Licencjonowanie" - LABEL_ABOUT_NAME: "O skrypcie" + LABEL_ABOUT_NAME: "O programie" TAB_GENERAL: LEGEND_INTERFACE: "Interfejs" - LABEL_LANGUAGE: "Język:" - LABEL_LANGUAGE_ADMIN: "Język (admin):" - LABEL_THEME: "Motyw:" + LABEL_LANGUAGE: "Język" + LABEL_LANGUAGE_ADMIN: "Język (admin)" + LABEL_THEME: "Motyw" LABEL_ALLOW_LANGUAGES_ON_SETTINGS: "Zezwól użytkownikowi na wybór języka" LABEL_ALLOW_THEMES_ON_SETTINGS: "Zezwól użytkownikowi na zmianę motywu" LABEL_ALLOW_BACKGROUND_ON_SETTINGS: "Zezwól użytkownikowi na użycie własnego tła" @@ -30,63 +30,64 @@ pl_PL: LABEL_SHOW_THUMBNAILS: "Pokaż miniatury (załączniki)" LABEL_ALLOW_GRAVATAR: "Zezwól na używanie gravatarów" LEGEND_MAIN: "Główne" - LABEL_ATTACHMENT_SIZE_LIMIT: "Maks. rozmiar zał.:" + LABEL_ATTACHMENT_SIZE_LIMIT: "Maksymalny rozmiar załącznika" LABEL_ALLOW_ADDITIONAL_ACCOUNTS: "Zezwól na dodatkowe konta" LABEL_ALLOW_IDENTITIES: "Zezwól na posiadanie wielu tożsamości" LABEL_ALLOW_TEMPLATES: "Zezwól na używanie szablonów" + ALERT_DATA_ACCESS: "Folder data jest osiągalny z poziomu przeglądarki WWW. Zmień konfigurację serwera www, aby ukryć ten folder z zewnątrz. Więcej informacji tutaj: " ALERT_WARNING: "Ostrzeżenie!" HTML_ALERT_WEAK_PASSWORD: | Korzystasz z domyślnego hasła administratora.
- Ze względów bezpieczeństwa, proszę - zmienić hasło + Ze względów bezpieczeństwa + zmień hasło na inne. TAB_LOGIN: - LEGEND_LOGIN_SCREEN: "Logowanie" - LABEL_DEFAULT_DOMAIN: "Domyślna domena:" + LEGEND_LOGIN_SCREEN: "Ekran logowania" + LABEL_DEFAULT_DOMAIN: "Domyślna domena" LABEL_DETERMINE_USER_DOMAIN: "Spróbuj określić domenę użytkownika" - LABEL_ALLOW_LANGUAGES_ON_LOGIN: "Zezwól na zmianę języka podczas logowania" + LABEL_ALLOW_LANGUAGES_ON_LOGIN: "Zezwól na zmianę języka na ekranie logowania" LABEL_DETERMINE_USER_LANGUAGE: "Spróbuj określić język użytkownika" TAB_BRANDING: LEGEND_BRANDING: "Personalizacja" - LABEL_PAGE_TITLE: "Tytuł strony:" - LABEL_LOADING_DESCRIPTION: "Komunikat ład. strony:" - LABEL_FAVICON_URL: "Favicon:" + LABEL_PAGE_TITLE: "Tytuł strony" + LABEL_LOADING_DESCRIPTION: "Komunikat ładowania strony" + LABEL_FAVICON_URL: "Favicon" LEGEND_LOGIN: "Login" - LABEL_LOGIN_LOGO: "Logo:" - LABEL_LOGIN_DESCRIPTION: "Opis:" - LABEL_LOGIN_BACKGROUND: "Tło:" - LABEL_LOGIN_CUSTOM_CSS: "Własny arkusz stylów:" - LABEL_LOGIN_SHOW_POWERED_LINK: "Pokaż link: \"Powered by RainLoop\"" + LABEL_LOGIN_LOGO: "Logo" + LABEL_LOGIN_DESCRIPTION: "Opis" + LABEL_LOGIN_BACKGROUND: "Tło" + LABEL_LOGIN_CUSTOM_CSS: "Własny arkusz styli CSS" + LABEL_LOGIN_SHOW_POWERED_LINK: "Pokaż link \"Powered by RainLoop\"" LEGEND_USER: "Użytkownik" - LABEL_USER_LOGO: "Logo:" - LABEL_USER_LOGO_TITLE: "Tytuł loga:" - LABEL_USER_LOGO_MESSAGE: "Logo (widok wiad.)" - LABEL_USER_CUSTOM_CSS: "Własny arkusz stylów:" - LEGEND_WELCOME_PAGE: "Str. główna" - LABEL_WELCOME_PAGE_TITLE: "Tytuł:" - LABEL_WELCOME_PAGE_URL: "Adres URL:" - LABEL_WELCOME_PAGE_DISPLAY: "Wyświetl:" - OPTION_WELCOME_PAGE_DISPLAY_NONE: "nigdy" - OPTION_WELCOME_PAGE_DISPLAY_ONCE: "raz" - OPTION_WELCOME_PAGE_DISPLAY_ALWAYS: "zawsze" - HTML_ALERT_PREMIUM: "Ta opcja jest dostępna tylko dla licencji Premium." TAB_CONTACTS: LEGEND_CONTACTS: "Kontakty" LEGEND_STORAGE: "Baza danych (PDO)" LABEL_ENABLE_CONTACTS: "Włącz kontakty" LABEL_ALLOW_SYNC: "Zezwól na synchronizację kontaktów (przy użyciu zewnętrznego serwera CardDAV)" - LABEL_STORAGE_TYPE: "Typ:" - LABEL_STORAGE_DSN: "Adres DSN:" - LABEL_STORAGE_USER: "Użytkownik:" - LABEL_STORAGE_PASSWORD: "Hasło:" + LABEL_STORAGE_TYPE: "Typ" + LABEL_STORAGE_DSN: "Adres DSN" + LABEL_STORAGE_USER: "Użytkownik" + LABEL_STORAGE_PASSWORD: "Hasło" BUTTON_TEST: "Testuj" ALERT_NOTICE: "Powiadomienie!" HTML_ALERT_DO_NOT_USE_THIS_DATABASE: "Nie używaj tej bazy danych z dużą ilością aktywnych użytkowników." HTML_ALERT_DOES_NOT_SUPPORTED: | Twój system nie zawiera wsparcia dla obsługi kontaktów.
- Musisz zainstalować lub uruchomić na serwerze jedno z rozszerzeń PDO (SQLite / MySQL / PostgreSQL). + Musisz zainstalować lub uruchomić na serwerze jedno z rozszerzeń PDO (SQLite / MySQL / PostgreSQL). TAB_DOMAINS: LEGEND_DOMAINS: "Domeny" BUTTON_ADD_DOMAIN: "Dodaj domenę" @@ -98,42 +99,42 @@ pl_PL: Kliknij na nazwę, aby skonfigurować domenę. TAB_SECURITY: LEGEND_SECURITY: "Bezpieczeństwo" - LABEL_ALLOW_TWO_STEP: "Zezwól na dwuskładnikową autoryzację" - LABEL_FORCE_TWO_STEP: "Wymuś dwuskładnikową autoryzację" + LABEL_ALLOW_TWO_STEP: "Zezwól na autoryzację 2-etapową" + LABEL_FORCE_TWO_STEP: "Wymuś autoryzację 2-etapową" LABEL_USE_IMAGE_PROXY: "Użyj lokalnego serwera proxy dla zewnętrznych obrazów" - LABEL_ALLOW_OPEN_PGP: "Zezwól na użycie OpenPGP" + LABEL_ALLOW_OPEN_PGP: "Zezwalaj na używanie OpenPGP" LABEL_SHOW_PHP_INFO: "Pokaż informacje o wersji PHP" LEGEND_ADMIN_PANEL_ACCESS_CREDENTIALS: "Dane dostępowe panelu administracyjnego" - LABEL_CURRENT_PASSWORD: "Bieżące hasło:" - LABEL_NEW_LOGIN: "Nowy login:" - LABEL_NEW_PASSWORD: "Nowe hasło:" - LABEL_REPEAT_PASSWORD: "Powtórz hasło:" + LABEL_CURRENT_PASSWORD: "Bieżące hasło" + LABEL_NEW_LOGIN: "Nowy login" + LABEL_NEW_PASSWORD: "Nowe hasło" + LABEL_REPEAT_PASSWORD: "Powtórz hasło" BUTTON_UPDATE_PASSWORD: "Zaktualizuj hasło" LEGEND_SSL: "SSL" LABEL_REQUIRE_VERIFICATION: "Wymagaj sprawdzania poprawności certyfikatów SSL (IMAP/SMTP)" - LABEL_ALLOW_SELF_SIGNED: "Zezwól na używanie certyfikatów podpisanych przez siebie" + LABEL_ALLOW_SELF_SIGNED: "Zezwól na używanie certyfikatów podpisanych samodzielnie" TAB_INTEGRATIONS: LEGEND_GOOGLE: "Google" - LABEL_ENABLE_GOOGLE: "Włącz obsługę platformy Google" + LABEL_ENABLE_GOOGLE: "Włącz integrację z Google" LABEL_GOOGLE_AUTH: "Autoryzacja" - LABEL_GOOGLE_DRIVE: "Obsługa dysku Google (widok tworz. wiadomości)" - LABEL_GOOGLE_PREVIEW: "Obsługa przeglądarki Google (podgląd dla plików: Microsoft Word, Excel i PowerPoint)" - LABEL_GOOGLE_CLIENT_ID: "Identyfikator:" - LABEL_GOOGLE_CLIENT_SECRET: "Hasło:" - LABEL_GOOGLE_API_KEY: "Klucz API:" - HINT_GOOGLE_API_KEY: "Wymagane dla obsługi interfejsu usługi: 'Dysk Google'" + LABEL_GOOGLE_DRIVE: "Obsługa dysku Google (widok tworzenia wiadomości)" + LABEL_GOOGLE_PREVIEW: "Obsługa przeglądarki Google (podgląd dla plików Microsoft Word, Excel i PowerPoint)" + LABEL_GOOGLE_CLIENT_ID: "Identyfikator klienta" + LABEL_GOOGLE_CLIENT_SECRET: "Hasło" + LABEL_GOOGLE_API_KEY: "Klucz API" + HINT_GOOGLE_API_KEY: "Wymagane dla obsługi interfejsu usługi 'Dysk Google'" LEGEND_FACEBOOK: "Facebook" - LABEL_ENABLE_FACEBOOK: "Włącz obsługę platformy Facebook (autoryzacja)" - LABEL_FACEBOOK_APP_ID: "Identyfikator aplikacji:" - LABEL_FACEBOOK_APP_SECRET: "Hasło aplikacji:" + LABEL_ENABLE_FACEBOOK: "Włącz integrację z Facebook (autoryzacja)" + LABEL_FACEBOOK_APP_ID: "Identyfikator aplikacji" + LABEL_FACEBOOK_APP_SECRET: "Hasło aplikacji" LEGEND_TWITTER: "Twitter" - LABEL_ENABLE_TWITTER: "Włącz obsługę platformy Twitter (autoryzacja)" - LABEL_TWITTER_CONSUMER_KEY: "Klucz użytkownika:" - LABEL_TWITTER_CONSUMER_SECRET: "Hasło użytkownika:" + LABEL_ENABLE_TWITTER: "Włącz integrację z Twitter (autoryzacja)" + LABEL_TWITTER_CONSUMER_KEY: "Klucz użytkownika" + LABEL_TWITTER_CONSUMER_SECRET: "Hasło użytkownika" LEGEND_DROPBOX: "Dropbox" - LABEL_ENABLE_DROPBOX: "Włącz obsługę platformy Dropbox" - LABEL_DROPBOX_API_KEY: "Klucz API:" - TOP_ALERT: "Szczegółowe informacje na temat obsługi platform, można znaleźść pod adresem: " + LABEL_ENABLE_DROPBOX: "Włącz integrację z Dropbox" + LABEL_DROPBOX_API_KEY: "Klucz API" + TOP_ALERT: "Szczegółowe informacje na temat obsługi platform, można znaleźć pod adresem " TAB_PLUGINS: LEGEND_PLUGINS: "Wtyczki" LABEL_ENABLE_PLUGINS: "Włącz obsługę wtyczek" @@ -141,53 +142,53 @@ pl_PL: LINK_INSTALL_NEW: "Kliknij tutaj, aby zainstalować nowe wtyczki!" HINT_CLICK_NAME: "Kliknij na nazwę, aby skonfigurować wtyczkę." TAB_PACKAGES: - LEGEND_AVAILABLE_FOR_UPDATE: "Aktualizacja" - LEGEND_AVAILABLE_FOR_INSTALLATION: "Do zainstalowania" - LEGEND_INSTALLED_PACKAGES: "Zainstalowane" + LEGEND_AVAILABLE_FOR_UPDATE: "Dostępna do aktualizacji" + LEGEND_AVAILABLE_FOR_INSTALLATION: "Dostępna do zainstalowania" + LEGEND_INSTALLED_PACKAGES: "Zainstalowane pakiety" ALERT_CANNOT_ACCESS_REPOSITORY: "Nie można uzyskać dostępu do repozytorium." TAB_LICENSING: - LABEL_YOUR_DOMAIN: "Domena:" - LABEL_VERSION: "Wersja:" - LABEL_CHECKING: "sprawdzanie..." + LABEL_YOUR_DOMAIN: "Twoja domena" + LABEL_VERSION: "Wersja" + LABEL_CHECKING: "Sprawdzanie..." TYPE_BASIC_HINT: "Ta domena nie jest licencjonowana do użytku komercyjnego." TYPE_BASIC_HINT_2: "Nie można dodać licencji dla tej domeny." - HTML_ALERT_TOP_1: "RainLoop Webmail korzysta z licencji:" - HTML_ALERT_TOP_2: "Możesz używać tego klienta za darmo, tylko dla prywatnych (własnych) projektów." + HTML_ALERT_TOP_1: "RainLoop Webmail korzysta z licencji" + HTML_ALERT_TOP_2: "Możesz używać tego klienta za darmo, tylko do celów prywatnych." HTML_ALERT_TOP_3: | - Do komercyjnego użytku (używania dodatkowych opcji) RainLoop Webmail, wymagane jest posiadanie + Do użytku komercyjnego (z dodatkowymi opcjami) RainLoop Webmail, wymagane jest posiadanie ważnej subskrypcji. TYPE_PREMIUM_LIFETIME: "Dożywotnia" - LABEL_SUB_EXPIRES: "Subskrypcja wygasa:" - BUTTON_ACTIVATE: "Aktywuj klucz" + LABEL_SUB_EXPIRES: "Subskrypcja wygasa" + BUTTON_ACTIVATE: "Aktywuj klucz dla tej domeny" BUTTON_PURCHASE: "Kup klucz" BUTTON_TRIAL: "Wersja testowa" TAB_ABOUT: - LEGEND_ABOUT: "O skrypcie" + LEGEND_ABOUT: "O programie" LABEL_TAG_HINT: "Prosty, nowoczesny i szybki klient pocztowy" LABEL_ALL_RIGHTS_RESERVED: "Wszystkie prawa zastrzeżone." - HINT_READ_CHANGE_LOG: "Przed aktualizacją, proszę przeczytać listę zmian." - HINT_IS_UP_TO_DATE: "Klient RainLoop jest aktualny." + HINT_READ_CHANGE_LOG: "Przed aktualizacją przeczytaj proszę listę zmian." + HINT_IS_UP_TO_DATE: "RainLoop jest aktualny." HTML_NEW_VERSION: "Dostępna jest nowa wersja: %VERSION%." - LABEL_UPDATING: "Aktualizowanie..." + LABEL_UPDATING: "Aktualizacja w toku..." LABEL_CHECKING: "Szukanie aktualizacji..." BUTTON_UPDATE: "Zaktualizuj" BUTTON_DOWNLOAD: "Pobierz" BUTTON_CHANGELOG: "Lista zmian" POPUPS_ACTIVATE: - TITLE_ACTIVATE: "Aktywacja klucza subskrypcji" - TITLE_ACTIVATION: "Aktywowanie..." - LABEL_DOMAIN: "Domena:" - LABEL_SUB_KEY: "Klucz subskrypcji:" + TITLE_ACTIVATE: "Czy chcesz aktywować klucz subskrypcji?" + TITLE_ACTIVATION: "Aktywacja w toku..." + LABEL_DOMAIN: "Domena" + LABEL_SUB_KEY: "Klucz subskrypcji" BUTTON_ACTIVATE: "Aktywuj" LABEL_ACTIVATED: "Aktywowano" ERROR_INVALID_SUBS_KEY: "Niepoprawny klucz subskrypcji" - SUBS_KEY_ACTIVATED: "Aktywowano klucz subskrypcji" + SUBS_KEY_ACTIVATED: "Poprawnie aktywowano klucz subskrypcji" HTML_DESC: | - Subskrypcja premium dla domeny: %DOMAIN%, zostanie przedłużona po aktywacji. + Subskrypcja premium dla domeny %DOMAIN%, zostanie przedłużona po aktywacji.
- Zwróc uwagę, że klucz subskrypcji może być aktywowany tylko dla jednej domeny. + Zwróć uwagę, że klucz subskrypcji może być aktywowany tylko dla jednej domeny.

- Po uruchomieniu aktywacji, nie można jej przerwac lub anulować. + Po uruchomieniu aktywacji, nie można jej przerwać lub anulować. POPUPS_DOMAIN_ALIAS: TITLE_ADD_DOMAIN_ALIAS: "Dodaj Alias" LABEL_ALIAS: "Alias" @@ -196,16 +197,16 @@ pl_PL: BUTTON_ADD: "Dodaj" POPUPS_DOMAIN: TITLE_ADD_DOMAIN: "Dodawanie domeny" - TITLE_ADD_DOMAIN_WITH_NAME: "Dodawanie domeny: \"%NAME%\"" - TITLE_EDIT_DOMAIN: "Edycja domeny: \"%NAME%\"" + TITLE_ADD_DOMAIN_WITH_NAME: "Dodawanie domeny \"%NAME%\"" + TITLE_EDIT_DOMAIN: "Edycja domeny \"%NAME%\"" LABEL_NAME: "Nazwa" NAME_HELPER: "obsługiwany znak wieloznaczności - *" LABEL_IMAP: "IMAP" LABEL_SMTP: "SMTP" LABEL_SIEVE: "SIEVE" - LABEL_SERVER: "Serwer:" - LABEL_PORT: "Port:" - LABEL_SECURE: "Rodzaj połączenia:" + LABEL_SERVER: "Serwer" + LABEL_PORT: "Port" + LABEL_SECURE: "Rodzaj połączenia" LABEL_WHITE_LIST: "Biała lista" SECURE_OPTION_NONE: "Bez zabezpieczeń" SECURE_OPTION_SSL: "SSL/TLS" @@ -214,7 +215,7 @@ pl_PL: LABEL_ALLOW_USER_SCRIPT: "Zezwól na spersonalizowany skrypt użytkownika" LABEL_USE_SHORT_LOGIN: "Użyj krótkiego loginu" LABEL_USE_AUTH: "Użyj autoryzacji" - LABEL_USE_PHP_MAIL: "Użyj funkcji php: 'mail()'" + LABEL_USE_PHP_MAIL: "Użyj funkcji php 'mail()'" BUTTON_TEST: "Test" BUTTON_WHITE_LIST: "Biała lista" BUTTON_SIEVE_CONFIGURATION: "Konfiguracja sieve" @@ -223,12 +224,12 @@ pl_PL: BUTTON_CLOSE: "Zamknij" BUTTON_ADD: "Dodaj" BUTTON_UPDATE: "Zaktualizuj" - NEW_DOMAIN_DESC: "Konfiguracja tej domeny pozwala na pracę
z adresami email: %NAME%" + NEW_DOMAIN_DESC: "Konfiguracja tej domeny pozwala na pracę
z adresami e-mail: %NAME%" WHITE_LIST_ALERT: | - Lista użytkowników domeny, którzy mogą uzyskać dostęp poprzez tego klienta. + Lista użytkowników domeny, którzy mogą uzyskać dostęp z tego webmaila. Użyj spacji do rozdzielenia. POPUPS_PLUGIN: - TITLE_PLUGIN: "Wtyczka: " + TITLE_PLUGIN: "Wtyczka" DESC_NOTHING_TO_CONFIGURE: "Brak opcji do skonfigurowania" BUTTON_CLOSE: "Zamknij" BUTTON_SAVE: "Zapisz" @@ -239,7 +240,7 @@ pl_PL: TITLE_LANGUAGES: "Wybierz swój język" HINTS: BETA: "Beta" - UNSTABLE: "Niestabilna" + UNSTABLE: "Niestabilne" WARNING: "Ostrzeżenie!" NOT_SUPPORTED: "nieobsługiwana" REQUIRES_PHP_54: "Wymaga PHP w wersji 5.4 lub wyższej" @@ -247,32 +248,32 @@ pl_PL: DOMAIN_ALREADY_EXISTS: "Ta domena już istnieje" UNKNOWN_ERROR: "Nieznany błąd" NOTIFICATIONS: - INVALID_TOKEN: "Nieważny token" + INVALID_TOKEN: "Nieprawidłowy token" AUTH_ERROR: "Autoryzacja zakończona niepowodzeniem" ACCESS_ERROR: "Błąd dostępu" CONNECTION_ERROR: "Nie można połączyć się z serwerem" CAPTCHA_ERROR: "Niepoprawny kod CAPTCHA." - SOCIAL_FACEBOOK_LOGIN_ACCESS_DISABLE: >- - Logowanie poprzez tą platformę, nie zostało jeszcze aktywowane dla żadnego + SOCIAL_FACEBOOK_LOGIN_ACCESS_DISABLE: > + Logowanie poprzez tą platformę nie zostało jeszcze aktywowane dla żadnego z kont e-mail. Zaloguj się używając loginu i hasła, a następnie włącz tą funkcję w ustawieniach konta. - SOCIAL_TWITTER_LOGIN_ACCESS_DISABLE: >- - Logowanie poprzez tą platformę, nie zostało jeszcze aktywowane dla żadnego + SOCIAL_TWITTER_LOGIN_ACCESS_DISABLE: > + Logowanie poprzez tą platformę nie zostało jeszcze aktywowane dla żadnego z kont e-mail. Zaloguj się używając loginu i hasła, a następnie włącz tą funkcję w ustawieniach konta. - SOCIAL_GOOGLE_LOGIN_ACCESS_DISABLE: >- - Logowanie poprzez tą platformę, nie zostało jeszcze aktywowane dla żadnego + SOCIAL_GOOGLE_LOGIN_ACCESS_DISABLE: > + Logowanie poprzez tą platformę nie zostało jeszcze aktywowane dla żadnego z kont e-mail. Zaloguj się używając loginu i hasła, a następnie włącz tą funkcję w ustawieniach konta. - DOMAIN_NOT_ALLOWED: "Brak zezwolenia na użycie tej domeny" - ACCOUNT_NOT_ALLOWED: "Brak zezwolenia dla tego konta" - ACCOUNT_TWO_FACTOR_AUTH_REQUIRED: "Wymagana dwuskładnikowa autoryzacja" - ACCOUNT_TWO_FACTOR_AUTH_ERROR: "Błąd autoryzacji dwuskładnikowej" + DOMAIN_NOT_ALLOWED: "Domena niedozwolona" + ACCOUNT_NOT_ALLOWED: "Konto jest niedozwolone" + ACCOUNT_TWO_FACTOR_AUTH_REQUIRED: "Wymagana autoryzacja dwuetapowa" + ACCOUNT_TWO_FACTOR_AUTH_ERROR: "Błąd autoryzacji dwuetapowej" COULD_NOT_SAVE_NEW_PASSWORD: "Nie można było zapisać nowego hasła" CURRENT_PASSWORD_INCORRECT: "Bieżące hasło jest niepoprawne" NEW_PASSWORD_SHORT: "Wybrane hasło jest za krótkie" NEW_PASSWORD_WEAK: "Wybrane hasło jest zbyt proste" - NEW_PASSWORD_FORBIDDENT: "Wybrane hasło zawiera zakazane znaki" + NEW_PASSWORD_FORBIDDENT: "Wybrane hasło zawiera niedozwolone znaki" CONTACTS_SYNC_ERROR: "Błąd synchronizacji kontaktów" CANT_GET_MESSAGE_LIST: "Nie można pobrać listy wiadomości" CANT_GET_MESSAGE: "Nie można pobrać wiadomości" @@ -309,17 +310,17 @@ pl_PL: UNKNOWN_ERROR: "Nieznany błąd" STATIC: BACK_LINK: "Odśwież" - DOMAIN_LIST_DESC: "Lista domen, do których można uzyskać dostęp za pomocą tego klienta." + DOMAIN_LIST_DESC: "Lista domen, do których można uzyskać dostęp za pomocą tego webmaila." PHP_EXSTENSIONS_ERROR_DESC: "Brak wymaganych rozszerzeń w konfiguracji PHP!" - PHP_VERSION_ERROR_DESC: "Twoja wersja PHP: (%VERSION%), jest niższa niż minimalna: 5.3.0!" - NO_SCRIPT_TITLE: "Ta aplikacja do poprawnej pracy wymaga javascript-u." + PHP_VERSION_ERROR_DESC: "Twoja wersja PHP (%VERSION%) jest niższa niż minimalna: 5.3.0!" + NO_SCRIPT_TITLE: "Ta aplikacja do poprawnej pracy wymaga JavaScript." NO_SCRIPT_DESC: | - Twoja przeglądarka nie obsługuje javascript-u. - Proszę o jego włączenie i ponowną próbę. + Twoja przeglądarka nie obsługuje JavaScript. + Włącz obsługę JavaScript i spróbuj ponownie. NO_COOKIE_TITLE: "Obsługa plików cookies jest wymagana dla poprawnego działania skryptu." NO_COOKIE_DESC: | Twoja przeglądarka nie obsługuje plików cookies. - Proszę o ich włączenie i ponowną próbę. + Włącz obsługę cookies i spróbuj ponownie. BAD_BROWSER_TITLE: "Posiadasz nieaktualną wersję przeglądarki." BAD_BROWSER_DESC: | W celu wykorzystania wszystkich funkcji tej aplikacji, diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/admin/pt_BR.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/admin/pt_BR.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/admin/pt_BR.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/admin/pt_BR.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/admin/ru_RU.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/admin/ru_RU.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/admin/ru_RU.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/admin/ru_RU.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/admin/sk_SK.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/admin/sk_SK.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/admin/sk_SK.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/admin/sk_SK.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/admin/sl_SI.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/admin/sl_SI.yml similarity index 98% rename from rainloop/app/rainloop/v/1.12.0/app/localization/admin/sl_SI.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/admin/sl_SI.yml index 13ef86afa7d8530ab75df65d775cbbc42fda43ce..f205a22b86e25b1b9d433c2344403732d0633404 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/localization/admin/sl_SI.yml +++ b/rainloop/app/rainloop/v/1.12.1/app/localization/admin/sl_SI.yml @@ -34,6 +34,7 @@ sl_SI: LABEL_ALLOW_ADDITIONAL_ACCOUNTS: "Dovoli dodatne račune" LABEL_ALLOW_IDENTITIES: "Dovoli več identitet" LABEL_ALLOW_TEMPLATES: "Dovoli predloge" + ALERT_DATA_ACCESS: "Mapa z RainLoop podatki je prosto ogledljiva. Prosimo, nastavite strežnik, da skrije mapo pred zunanjimi dostopi. Preberite več tukaj:" ALERT_WARNING: "Pozor!" HTML_ALERT_WEAK_PASSWORD: | V uporabi je privzeto geslo administratorja diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/admin/sv_SE.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/admin/sv_SE.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/admin/sv_SE.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/admin/sv_SE.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/admin/zh_CN.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/admin/zh_CN.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/admin/zh_CN.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/admin/zh_CN.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/langs.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/langs.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/langs.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/langs.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/af.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/af.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/af.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/af.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/ar-dz.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/ar-dz.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/ar-dz.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/ar-dz.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/ar-kw.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/ar-kw.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/ar-kw.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/ar-kw.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/ar-ly.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/ar-ly.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/ar-ly.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/ar-ly.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/ar-ma.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/ar-ma.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/ar-ma.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/ar-ma.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/ar-sa.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/ar-sa.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/ar-sa.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/ar-sa.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/ar-tn.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/ar-tn.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/ar-tn.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/ar-tn.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/ar.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/ar.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/ar.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/ar.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/az.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/az.js similarity index 98% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/az.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/az.js index 04930726ba481c820356b26c3d0d0c3be1e23adb..578b70c557ce86b6a06b48b277fe3ae4f076f955 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/az.js +++ b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/az.js @@ -55,7 +55,7 @@ relativeTime : { future : '%s sonra', past : '%s əvvəl', - s : 'birneçə saniyyə', + s : 'birneçə saniyə', ss : '%d saniyə', m : 'bir dəqiqə', mm : '%d dəqiqə', diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/be.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/be.js similarity index 98% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/be.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/be.js index 46a2a11f85a2d2936d6b502dcddbe790c677f218..db7a3c7633aedde02d013622849c0c5e05c1c37f 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/be.js +++ b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/be.js @@ -41,7 +41,7 @@ weekdays : { format: 'нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу'.split('_'), standalone: 'нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота'.split('_'), - isFormat: /\[ ?[Вв] ?(?:мінулую|наступную)? ?\] ?dddd/ + isFormat: /\[ ?[Ууў] ?(?:мінулую|наступную)? ?\] ?dddd/ }, weekdaysShort : 'нд_пн_ат_ср_чц_пт_сб'.split('_'), weekdaysMin : 'нд_пн_ат_ср_чц_пт_сб'.split('_'), diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/bg.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/bg.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/bg.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/bg.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/bm.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/bm.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/bm.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/bm.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/bn.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/bn.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/bn.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/bn.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/bo.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/bo.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/bo.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/bo.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/br.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/br.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/br.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/br.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/bs.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/bs.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/bs.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/bs.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/ca.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/ca.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/ca.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/ca.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/cs.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/cs.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/cs.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/cs.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/cv.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/cv.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/cv.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/cv.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/cy.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/cy.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/cy.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/cy.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/da.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/da.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/da.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/da.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/de-at.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/de-at.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/de-at.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/de-at.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/de-ch.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/de-ch.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/de-ch.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/de-ch.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/de.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/de.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/de.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/de.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/dv.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/dv.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/dv.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/dv.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/el.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/el.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/el.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/el.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/en-au.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/en-au.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/en-au.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/en-au.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/en-ca.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/en-ca.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/en-ca.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/en-ca.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/en-gb.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/en-gb.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/en-gb.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/en-gb.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/en-ie.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/en-ie.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/en-ie.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/en-ie.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/en-il.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/en-il.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/en-il.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/en-il.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/en-nz.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/en-nz.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/en-nz.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/en-nz.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/eo.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/eo.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/eo.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/eo.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/es-do.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/es-do.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/es-do.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/es-do.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/es-us.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/es-us.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/es-us.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/es-us.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/es.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/es.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/es.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/es.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/et.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/et.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/et.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/et.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/eu.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/eu.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/eu.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/eu.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/fa.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/fa.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/fa.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/fa.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/fi.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/fi.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/fi.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/fi.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/fo.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/fo.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/fo.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/fo.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/fr-ca.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/fr-ca.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/fr-ca.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/fr-ca.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/fr-ch.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/fr-ch.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/fr-ch.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/fr-ch.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/fr.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/fr.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/fr.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/fr.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/fy.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/fy.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/fy.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/fy.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/gd.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/gd.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/gd.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/gd.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/gl.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/gl.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/gl.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/gl.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/gom-latn.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/gom-latn.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/gom-latn.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/gom-latn.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/gu.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/gu.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/gu.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/gu.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/he.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/he.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/he.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/he.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/hi.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/hi.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/hi.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/hi.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/hr.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/hr.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/hr.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/hr.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/hu.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/hu.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/hu.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/hu.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/hy-am.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/hy-am.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/hy-am.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/hy-am.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/id.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/id.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/id.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/id.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/is.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/is.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/is.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/is.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/it.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/it.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/it.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/it.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/ja.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/ja.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/ja.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/ja.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/jv.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/jv.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/jv.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/jv.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/ka.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/ka.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/ka.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/ka.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/kk.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/kk.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/kk.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/kk.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/km.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/km.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/km.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/km.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/kn.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/kn.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/kn.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/kn.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/ko.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/ko.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/ko.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/ko.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/ky.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/ky.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/ky.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/ky.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/lb.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/lb.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/lb.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/lb.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/lo.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/lo.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/lo.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/lo.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/lt.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/lt.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/lt.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/lt.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/lv.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/lv.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/lv.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/lv.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/me.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/me.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/me.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/me.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/mi.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/mi.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/mi.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/mi.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/mk.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/mk.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/mk.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/mk.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/ml.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/ml.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/ml.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/ml.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/mn.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/mn.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/mn.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/mn.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/mr.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/mr.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/mr.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/mr.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/ms-my.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/ms-my.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/ms-my.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/ms-my.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/ms.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/ms.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/ms.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/ms.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/mt.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/mt.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/mt.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/mt.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/my.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/my.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/my.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/my.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/nb.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/nb.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/nb.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/nb.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/ne.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/ne.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/ne.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/ne.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/nl-be.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/nl-be.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/nl-be.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/nl-be.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/nl.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/nl.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/nl.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/nl.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/nn.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/nn.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/nn.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/nn.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/pa-in.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/pa-in.js similarity index 98% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/pa-in.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/pa-in.js index f17b8dd9ba07c849ca9dc14ad0ba4150878457ae..63f4f44ea304017b48e25a67e678c78a9b06736b 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/pa-in.js +++ b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/pa-in.js @@ -51,7 +51,7 @@ calendar : { sameDay : '[ਅਜ] LT', nextDay : '[ਕਲ] LT', - nextWeek : 'dddd, LT', + nextWeek : '[ਅਗਲਾ] dddd, LT', lastDay : '[ਕਲ] LT', lastWeek : '[ਪਿਛਲੇ] dddd, LT', sameElse : 'L' diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/pl.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/pl.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/pl.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/pl.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/pt-br.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/pt-br.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/pt-br.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/pt-br.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/pt.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/pt.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/pt.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/pt.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/ro.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/ro.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/ro.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/ro.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/ru.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/ru.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/ru.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/ru.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/sd.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/sd.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/sd.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/sd.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/se.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/se.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/se.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/se.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/si.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/si.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/si.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/si.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/sk.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/sk.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/sk.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/sk.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/sl.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/sl.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/sl.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/sl.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/sq.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/sq.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/sq.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/sq.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/sr-cyrl.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/sr-cyrl.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/sr-cyrl.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/sr-cyrl.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/sr.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/sr.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/sr.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/sr.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/ss.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/ss.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/ss.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/ss.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/sv.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/sv.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/sv.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/sv.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/sw.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/sw.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/sw.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/sw.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/ta.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/ta.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/ta.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/ta.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/te.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/te.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/te.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/te.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/tet.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/tet.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/tet.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/tet.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/tg.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/tg.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/tg.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/tg.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/th.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/th.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/th.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/th.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/tl-ph.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/tl-ph.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/tl-ph.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/tl-ph.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/tlh.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/tlh.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/tlh.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/tlh.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/tr.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/tr.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/tr.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/tr.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/tzl.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/tzl.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/tzl.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/tzl.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/tzm-latn.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/tzm-latn.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/tzm-latn.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/tzm-latn.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/tzm.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/tzm.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/tzm.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/tzm.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/ug-cn.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/ug-cn.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/ug-cn.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/ug-cn.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/uk.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/uk.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/uk.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/uk.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/ur.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/ur.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/ur.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/ur.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/uz-latn.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/uz-latn.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/uz-latn.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/uz-latn.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/uz.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/uz.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/uz.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/uz.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/vi.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/vi.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/vi.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/vi.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/x-pseudo.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/x-pseudo.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/x-pseudo.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/x-pseudo.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/yo.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/yo.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/yo.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/yo.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/zh-cn.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/zh-cn.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/zh-cn.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/zh-cn.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/zh-hk.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/zh-hk.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/zh-hk.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/zh-hk.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/moment/zh-tw.js b/rainloop/app/rainloop/v/1.12.1/app/localization/moment/zh-tw.js similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/moment/zh-tw.js rename to rainloop/app/rainloop/v/1.12.1/app/localization/moment/zh-tw.js diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/README b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/README similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/webmail/README rename to rainloop/app/rainloop/v/1.12.1/app/localization/webmail/README diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/_source.en.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/_source.en.yml similarity index 97% rename from rainloop/app/rainloop/v/1.12.0/app/localization/webmail/_source.en.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/webmail/_source.en.yml index f4f17c6092f93012db7ba2c2a40c5a6e36b95328..6cb01cb9095ab437b93bb375aa479ec21286dfc7 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/_source.en.yml +++ b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/_source.en.yml @@ -1,400 +1,400 @@ -en: - LOGIN: - LABEL_EMAIL: "Email" - LABEL_LOGIN: "Login" - LABEL_PASSWORD: "Password" - LABEL_SIGN_ME: "Remember Me" - LABEL_VERIFICATION_CODE: "Verification Code" - LABEL_DONT_ASK_VERIFICATION_CODE: "Don't ask for the code for 2 weeks" - BUTTON_SIGN_IN: "Sign In" - TITLE_SIGN_IN_GOOGLE: "Sign In using Google" - TITLE_SIGN_IN_FACEBOOK: "Sign In using Facebook" - TITLE_SIGN_IN_TWITTER: "Sign In using Twitter" - LABEL_FORGOT_PASSWORD: "Forgot password" - LABEL_REGISTRATION: "Registration" - TOP_TOOLBAR: - BUTTON_ADD_ACCOUNT: "Add Account" - BUTTON_SETTINGS: "Settings" - BUTTON_HELP: "Help" - BUTTON_LOGOUT: "Logout" - MOBILE: - BUTTON_MOBILE_VERSION: "Mobile version" - BUTTON_DESKTOP_VERSION: "Desktop version" - SEARCH: - MAIN_INPUT_PLACEHOLDER: "Search" - TITLE_ADV: "Advanced Search" - LABEL_ADV_FROM: "From" - LABEL_ADV_TO: "To" - LABEL_ADV_SUBJECT: "Subject" - LABEL_ADV_TEXT: "Text" - LABEL_ADV_HAS_ATTACHMENT: "Has attachment" - LABEL_ADV_HAS_ATTACHMENTS: "Has attachments" - LABEL_ADV_FLAGGED: "Flagged" - LABEL_ADV_UNSEEN: "Unseen" - LABEL_ADV_DATE: "Date" - LABEL_ADV_DATE_ALL: "All" - LABEL_ADV_DATE_3_DAYS: "Up to 3 days old" - LABEL_ADV_DATE_7_DAYS: "Up to 1 week old" - LABEL_ADV_DATE_MONTH: "Up to 1 month old" - LABEL_ADV_DATE_3_MONTHS: "Up to 3 months old" - LABEL_ADV_DATE_6_MONTHS: "Up to 6 months old" - LABEL_ADV_DATE_YEAR: "Up to 1 year old" - BUTTON_ADV_SEARCH: "Search" - PREVIEW_POPUP: - FULLSCREEN: "Toggle fullscreen" - ZOOM: "Zoom in/out" - CLOSE: "Close (Esc)" - LOADING: "Loading..." - GALLERY_PREV: "Previous (arrow left)" - GALLERY_NEXT: "Next (arrow right)" - GALLERY_COUNTER: "%curr% of %total%" - IMAGE_ERROR: "The image could not be loaded." - AJAX_ERROR: "The content could not be loaded." - FOLDER_LIST: - BUTTON_COMPOSE: "Compose" - BUTTON_CONTACTS: "Contacts" - BUTTON_NEW_MESSAGE: "New message" - INBOX_NAME: "Inbox" - SENT_NAME: "Sent" - DRAFTS_NAME: "Drafts" - SPAM_NAME: "Spam" - TRASH_NAME: "Trash" - ARCHIVE_NAME: "Archive" - QUOTA: - TITLE: "Quota usage" - MESSAGE_LIST: - BUTTON_RELOAD: "Reload Message List" - BUTTON_MOVE_TO: "Move To" - BUTTON_DELETE: "Delete" - BUTTON_ARCHIVE: "Archive" - BUTTON_SPAM: "Spam" - BUTTON_NOT_SPAM: "Not Spam" - BUTTON_EMPTY_FOLDER: "Clear Folder" - BUTTON_MULTY_FORWARD: "Forward as attachment(s)" - BUTTON_DELETE_WITHOUT_MOVE: "Delete permanently" - BUTTON_MORE: "More" - MENU_SET_SEEN: "Mark as read" - MENU_SET_ALL_SEEN: "Mark all as read" - MENU_UNSET_SEEN: "Mark as unread" - MENU_SET_FLAG: "Flag" - MENU_UNSET_FLAG: "Unflag" - MENU_SELECT_ALL: "All" - MENU_SELECT_NONE: "None" - MENU_SELECT_INVERT: "Invert" - MENU_SELECT_UNSEEN: "Unread" - MENU_SELECT_SEEN: "Read" - MENU_SELECT_FLAGGED: "Flagged" - MENU_SELECT_UNFLAGGED: "Unflagged" - EMPTY_LIST: "Empty list." - EMPTY_SEARCH_LIST: "No messages matched your search." - SEARCH_RESULT_FOR: "Search results for \"%SEARCH%\"" - BACK_TO_MESSAGE_LIST: "back to message list" - LIST_LOADING: "Loading" - EMPTY_SUBJECT_TEXT: "(No subject)" - PUT_MESSAGE_HERE: "Drop message here to view it in the list" - TODAY_AT: "today at %TIME%" - YESTERDAY_AT: "yesterday at %TIME%" - SEARCH_PLACEHOLDER: "Search" - NEW_MESSAGE_NOTIFICATION: "You have %COUNT% new messages!" - QUOTA_SIZE: "Using %SIZE% (%PROC%%) of your %LIMIT%" - MESSAGE: - BUTTON_EDIT: "Edit" - BUTTON_BACK: "Back" - BUTTON_CLOSE: "Close" - BUTTON_DELETE: "Delete" - BUTTON_UNSUBSCRIBE: "Unsubscribe from this list" - BUTTON_ARCHIVE: "Archive" - BUTTON_SPAM: "Spam" - BUTTON_NOT_SPAM: "Not Spam" - BUTTON_MOVE_TO: "Move To" - BUTTON_MORE: "More" - BUTTON_REPLY: "Reply" - BUTTON_REPLY_ALL: "Reply All" - BUTTON_FORWARD: "Forward" - BUTTON_FORWARD_AS_ATTACHMENT: "Forward as attachment" - BUTTON_EDIT_AS_NEW: "Edit as New" - BUTTON_SHOW_IMAGES: "Display external images" - BUTTON_NOTIFY_READ_RECEIPT: "The sender has asked to be notified when you read this message." - BUTTON_IN_NEW_WINDOW: "View in separate window" - BUTTON_THREAD_LIST: "Thread list" - BUTTON_THREAD_PREV: "Previous" - BUTTON_THREAD_NEXT: "Next" - BUTTON_THREAD_MORE: "More messages" - MENU_HEADERS: "Show message headers" - MENU_VIEW_ORIGINAL: "Show Source" - MENU_DOWNLOAD_ORIGINAL: "Download as .eml file" - MENU_FILTER_SIMILAR: "Filter messages like this" - MENU_PRINT: "Print" - EMPTY_SUBJECT_TEXT: "(No subject)" - LABEL_SUBJECT: "Subject" - LABEL_DATE: "Date" - LABEL_FROM: "From" - LABEL_FROM_SHORT: "from" - LABEL_TO: "To" - LABEL_TO_SHORT: "to" - LABEL_CC: "CC" - LABEL_BCC: "BCC" - LABEL_REPLY_TO: "Reply-To" - PRINT_LABEL_FROM: "From" - PRINT_LABEL_TO: "To" - PRINT_LABEL_CC: "CC" - PRINT_LABEL_BCC: "BCC" - PRINT_LABEL_REPLY_TO: "Reply-To" - PRINT_LABEL_DATE: "Date" - PRINT_LABEL_SUBJECT: "Subject" - PRINT_LABEL_ATTACHMENTS: "Attachments" - MESSAGE_LOADING: "Loading" - MESSAGE_VIEW_DESC: "Select any message in the list to view it here." - MESSAGE_VIEW_MOVE_DESC: "Click folder name in the left panel to select the destination." - PGP_PASSWORD_INPUT_PLACEHOLDER: "Password" - PGP_SIGNED_MESSAGE_DESC: "OpenPGP signed message (click to verify)" - PGP_ENCRYPTED_MESSAGE_DESC: "OpenPGP encrypted message (click to decrypt)" - LINK_DOWNLOAD_AS_ZIP: "Download as zip" - LINK_SAVE_TO_OWNCLOUD: "Save to ownCloud" - LINK_SAVE_TO_CLOUD: "Save to Cloud" - LINK_SAVE_TO_DROPBOX: "Save to Dropbox" - READ_RECEIPT: - SUBJECT: "Return Receipt (displayed) - %SUBJECT%" +en: + LOGIN: + LABEL_EMAIL: "Email" + LABEL_LOGIN: "Login" + LABEL_PASSWORD: "Password" + LABEL_SIGN_ME: "Remember Me" + LABEL_VERIFICATION_CODE: "Verification Code" + LABEL_DONT_ASK_VERIFICATION_CODE: "Don't ask for the code for 2 weeks" + BUTTON_SIGN_IN: "Sign In" + TITLE_SIGN_IN_GOOGLE: "Sign In using Google" + TITLE_SIGN_IN_FACEBOOK: "Sign In using Facebook" + TITLE_SIGN_IN_TWITTER: "Sign In using Twitter" + LABEL_FORGOT_PASSWORD: "Forgot password" + LABEL_REGISTRATION: "Registration" + TOP_TOOLBAR: + BUTTON_ADD_ACCOUNT: "Add Account" + BUTTON_SETTINGS: "Settings" + BUTTON_HELP: "Help" + BUTTON_LOGOUT: "Logout" + MOBILE: + BUTTON_MOBILE_VERSION: "Mobile version" + BUTTON_DESKTOP_VERSION: "Desktop version" + SEARCH: + MAIN_INPUT_PLACEHOLDER: "Search" + TITLE_ADV: "Advanced Search" + LABEL_ADV_FROM: "From" + LABEL_ADV_TO: "To" + LABEL_ADV_SUBJECT: "Subject" + LABEL_ADV_TEXT: "Text" + LABEL_ADV_HAS_ATTACHMENT: "Has attachment" + LABEL_ADV_HAS_ATTACHMENTS: "Has attachments" + LABEL_ADV_FLAGGED: "Flagged" + LABEL_ADV_UNSEEN: "Unseen" + LABEL_ADV_DATE: "Date" + LABEL_ADV_DATE_ALL: "All" + LABEL_ADV_DATE_3_DAYS: "Up to 3 days old" + LABEL_ADV_DATE_7_DAYS: "Up to 1 week old" + LABEL_ADV_DATE_MONTH: "Up to 1 month old" + LABEL_ADV_DATE_3_MONTHS: "Up to 3 months old" + LABEL_ADV_DATE_6_MONTHS: "Up to 6 months old" + LABEL_ADV_DATE_YEAR: "Up to 1 year old" + BUTTON_ADV_SEARCH: "Search" + PREVIEW_POPUP: + FULLSCREEN: "Toggle fullscreen" + ZOOM: "Zoom in/out" + CLOSE: "Close (Esc)" + LOADING: "Loading..." + GALLERY_PREV: "Previous (arrow left)" + GALLERY_NEXT: "Next (arrow right)" + GALLERY_COUNTER: "%curr% of %total%" + IMAGE_ERROR: "The image could not be loaded." + AJAX_ERROR: "The content could not be loaded." + FOLDER_LIST: + BUTTON_COMPOSE: "Compose" + BUTTON_CONTACTS: "Contacts" + BUTTON_NEW_MESSAGE: "New message" + INBOX_NAME: "Inbox" + SENT_NAME: "Sent" + DRAFTS_NAME: "Drafts" + SPAM_NAME: "Spam" + TRASH_NAME: "Trash" + ARCHIVE_NAME: "Archive" + QUOTA: + TITLE: "Quota usage" + MESSAGE_LIST: + BUTTON_RELOAD: "Reload Message List" + BUTTON_MOVE_TO: "Move To" + BUTTON_DELETE: "Delete" + BUTTON_ARCHIVE: "Archive" + BUTTON_SPAM: "Spam" + BUTTON_NOT_SPAM: "Not Spam" + BUTTON_EMPTY_FOLDER: "Clear Folder" + BUTTON_MULTY_FORWARD: "Forward as attachment(s)" + BUTTON_DELETE_WITHOUT_MOVE: "Delete permanently" + BUTTON_MORE: "More" + MENU_SET_SEEN: "Mark as read" + MENU_SET_ALL_SEEN: "Mark all as read" + MENU_UNSET_SEEN: "Mark as unread" + MENU_SET_FLAG: "Flag" + MENU_UNSET_FLAG: "Unflag" + MENU_SELECT_ALL: "All" + MENU_SELECT_NONE: "None" + MENU_SELECT_INVERT: "Invert" + MENU_SELECT_UNSEEN: "Unread" + MENU_SELECT_SEEN: "Read" + MENU_SELECT_FLAGGED: "Flagged" + MENU_SELECT_UNFLAGGED: "Unflagged" + EMPTY_LIST: "Empty list." + EMPTY_SEARCH_LIST: "No messages matched your search." + SEARCH_RESULT_FOR: "Search results for \"%SEARCH%\"" + BACK_TO_MESSAGE_LIST: "back to message list" + LIST_LOADING: "Loading" + EMPTY_SUBJECT_TEXT: "(No subject)" + PUT_MESSAGE_HERE: "Drop message here to view it in the list" + TODAY_AT: "today at %TIME%" + YESTERDAY_AT: "yesterday at %TIME%" + SEARCH_PLACEHOLDER: "Search" + NEW_MESSAGE_NOTIFICATION: "You have %COUNT% new messages!" + QUOTA_SIZE: "Using %SIZE% (%PROC%%) of your %LIMIT%" + MESSAGE: + BUTTON_EDIT: "Edit" + BUTTON_BACK: "Back" + BUTTON_CLOSE: "Close" + BUTTON_DELETE: "Delete" + BUTTON_UNSUBSCRIBE: "Unsubscribe from this list" + BUTTON_ARCHIVE: "Archive" + BUTTON_SPAM: "Spam" + BUTTON_NOT_SPAM: "Not Spam" + BUTTON_MOVE_TO: "Move To" + BUTTON_MORE: "More" + BUTTON_REPLY: "Reply" + BUTTON_REPLY_ALL: "Reply All" + BUTTON_FORWARD: "Forward" + BUTTON_FORWARD_AS_ATTACHMENT: "Forward as attachment" + BUTTON_EDIT_AS_NEW: "Edit as New" + BUTTON_SHOW_IMAGES: "Display external images" + BUTTON_NOTIFY_READ_RECEIPT: "The sender has asked to be notified when you read this message." + BUTTON_IN_NEW_WINDOW: "View in separate window" + BUTTON_THREAD_LIST: "Thread list" + BUTTON_THREAD_PREV: "Previous" + BUTTON_THREAD_NEXT: "Next" + BUTTON_THREAD_MORE: "More messages" + MENU_HEADERS: "Show message headers" + MENU_VIEW_ORIGINAL: "Show Source" + MENU_DOWNLOAD_ORIGINAL: "Download as .eml file" + MENU_FILTER_SIMILAR: "Filter messages like this" + MENU_PRINT: "Print" + EMPTY_SUBJECT_TEXT: "(No subject)" + LABEL_SUBJECT: "Subject" + LABEL_DATE: "Date" + LABEL_FROM: "From" + LABEL_FROM_SHORT: "from" + LABEL_TO: "To" + LABEL_TO_SHORT: "to" + LABEL_CC: "CC" + LABEL_BCC: "BCC" + LABEL_REPLY_TO: "Reply-To" + PRINT_LABEL_FROM: "From" + PRINT_LABEL_TO: "To" + PRINT_LABEL_CC: "CC" + PRINT_LABEL_BCC: "BCC" + PRINT_LABEL_REPLY_TO: "Reply-To" + PRINT_LABEL_DATE: "Date" + PRINT_LABEL_SUBJECT: "Subject" + PRINT_LABEL_ATTACHMENTS: "Attachments" + MESSAGE_LOADING: "Loading" + MESSAGE_VIEW_DESC: "Select any message in the list to view it here." + MESSAGE_VIEW_MOVE_DESC: "Click folder name in the left panel to select the destination." + PGP_PASSWORD_INPUT_PLACEHOLDER: "Password" + PGP_SIGNED_MESSAGE_DESC: "OpenPGP signed message (click to verify)" + PGP_ENCRYPTED_MESSAGE_DESC: "OpenPGP encrypted message (click to decrypt)" + LINK_DOWNLOAD_AS_ZIP: "Download as zip" + LINK_SAVE_TO_OWNCLOUD: "Save to ownCloud" + LINK_SAVE_TO_CLOUD: "Save to Cloud" + LINK_SAVE_TO_DROPBOX: "Save to Dropbox" + READ_RECEIPT: + SUBJECT: "Return Receipt (displayed) - %SUBJECT%" BODY: | This is a Return Receipt for the mail that you sent to %READ-RECEIPT%. Note: "This Return Receipt only acknowledges that the message was displayed on the recipient's computer." There is no guarantee that the recipient has read or understood the message contents. - SUGGESTIONS: - SEARCHING_DESC: "Searching..." - CONTACTS: - LEGEND_CONTACTS: "Contacts" - SEARCH_INPUT_PLACEHOLDER: "Search" - BUTTON_ADD_CONTACT: "Add Contact" - BUTTON_CREATE_CONTACT: "Create" - BUTTON_UPDATE_CONTACT: "Update" - BUTTON_IMPORT: "Import (csv, vcf, vCard)" - BUTTON_EXPORT_VCARD: "Export (vcf, vCard)" - BUTTON_EXPORT_CSV: "Export (csv)" - ERROR_IMPORT_FILE: "Import error (invalid file format)" - LIST_LOADING: "Loading" - EMPTY_LIST: "No contacts here" - EMPTY_SEARCH: "No contacts found" - CLEAR_SEARCH: "Clear search" - CONTACT_VIEW_DESC: "Select contact in the list to view it here." - LABEL_DISPLAY_NAME: "Display name" - LABEL_EMAIL: "Email" - LABEL_PHONE: "Phone" - LABEL_WEB: "Web" - LABEL_BIRTHDAY: "Birthday" - LINK_ADD_EMAIL: "Add an email address" - LINK_ADD_PHONE: "Add a phone" - LINK_BIRTHDAY: "Birthday" - PLACEHOLDER_ENTER_DISPLAY_NAME: "Enter display name" - PLACEHOLDER_ENTER_LAST_NAME: "Enter last name" - PLACEHOLDER_ENTER_FIRST_NAME: "Enter first name" - PLACEHOLDER_ENTER_NICK_NAME: "Enter nickname" - LABEL_READ_ONLY: "Read only" - LABEL_SHARE: "Share" - ADD_MENU_LABEL: "Add" - ADD_MENU_NICKNAME: "Nickname" - ADD_MENU_NOTES: "Notes" - ADD_MENU_EMAIL: "Email" - ADD_MENU_PHONE: "Phone" - ADD_MENU_URL: "URL" - ADD_MENU_ADDRESS: "Address" - ADD_MENU_BIRTHDAY: "Birthday" - ADD_MENU_TAGS: "Tags" - BUTTON_SHARE_NONE: "None" - BUTTON_SHARE_ALL: "Everyone" - BUTTON_SYNC: "Synchronization (CardDAV)" - COMPOSE: - TITLE_FROM: "From" - TITLE_TO: "To" - TITLE_CC: "CC" - TITLE_BCC: "BCC" - TITLE_REPLY_TO: "Reply-To" - TITLE_SUBJECT: "Subject" - LINK_SHOW_INPUTS: "show all fields" - BUTTON_SEND: "Send" - BUTTON_SAVE: "Save" - BUTTON_DELETE: "Delete" - BUTTON_CANCEL: "Cancel" - BUTTON_MINIMIZE: "Minimize" - SAVED_TIME: "Saved at %TIME%" - SAVED_ERROR_ON_SEND: "Message was sent but not saved to sent items folder" - DISCARD_UNSAVED_DATA: "Discard unsaved data?" - ATTACH_FILES: "Attach files" - ATTACH_DROP_FILES_DESC: "Drop files here" - ATTACH_ITEM_CANCEL: "Cancel" - DROPBOX: "Dropbox" - GOOGLE_DRIVE: "Google Drive" - REPLY_MESSAGE_TITLE: "%DATETIME%, %EMAIL% wrote" - FORWARD_MESSAGE_TOP_TITLE: "-------- Forwarded message -------" - FORWARD_MESSAGE_TOP_FROM: "From" - FORWARD_MESSAGE_TOP_TO: "To" - FORWARD_MESSAGE_TOP_CC: "CC" - FORWARD_MESSAGE_TOP_SENT: "Sent" - FORWARD_MESSAGE_TOP_SUBJECT: "Subject" - EMPTY_TO_ERROR_DESC: "Please specify at least one recipient" - NO_ATTACHMENTS_HERE_DESC: "No attachments here." - ATTACHMENTS_ERROR_DESC: "Warning! Not all attachments have been uploaded." - ATTACHMENTS_UPLOAD_ERROR_DESC: "Not all attachments have been uploaded yet." - BUTTON_REQUEST_READ_RECEIPT: "Request a read receipt" - BUTTON_MARK_AS_IMPORTANT: "Mark as important" - BUTTON_OPEN_PGP: "OpenPGP (Plain Text Only)" - BUTTON_REQUEST_DSN: "Request a delivery receipt" - POPUPS_WELCOME_PAGE: - BUTTON_CLOSE: "Close" - POPUPS_ASK: - BUTTON_YES: "Yes" - BUTTON_NO: "No" - DESC_WANT_CLOSE_THIS_WINDOW: "Are you sure you want to close this window?" - DESC_WANT_DELETE_MESSAGES: "Are you sure you want to delete the message(s)?" - POPUPS_LANGUAGES: - TITLE_LANGUAGES: "Choose your language" - POPUPS_ADD_ACCOUNT: - TITLE_ADD_ACCOUNT: "Add Account?" - BUTTON_ADD_ACCOUNT: "Add" - TITLE_UPDATE_ACCOUNT: "Update Account?" - BUTTON_UPDATE_ACCOUNT: "Update" - POPUPS_IDENTITY: - TITLE_ADD_IDENTITY: "Add Identity?" - TITLE_UPDATE_IDENTITY: "Update Identity?" - BUTTON_ADD_IDENTITY: "Add" - BUTTON_UPDATE_IDENTITY: "Update" - LABEL_EMAIL: "Email" - LABEL_NAME: "Name" - LABEL_REPLY_TO: "Reply-To" - LABEL_SIGNATURE: "Signature" - LABEL_CC: "Cc" - LABEL_BCC: "Bcc" - LABEL_SIGNATURE_INSERT_BEFORE: "Insert this signature before quoted text in replies" - POPUPS_CREATE_FOLDER: - TITLE_CREATE_FOLDER: "Create a folder?" - LABEL_NAME: "Folder name" - LABEL_PARENT: "Parent folder" - BUTTON_CREATE: "Create" - BUTTON_CANCEL: "Cancel" - BUTTON_CLOSE: "Close" - TITLE_CREATING_PROCESS: "Creating a folder" - POPUPS_CLEAR_FOLDER: - TITLE_CLEAR_FOLDER: "Purge all messages from the folder?" - BUTTON_CLEAR: "Clear" - BUTTON_CANCEL: "Cancel" - BUTTON_CLOSE: "Close" - DANGER_DESC_WARNING: "Warning!" - DANGER_DESC_HTML_1: "This action will result in removing all mails from %FOLDER% folder completely." - DANGER_DESC_HTML_2: "Once started, the process cannot be aborted or cancelled." - TITLE_CLEARING_PROCESS: "Purging the folder..." - POPUPS_IMPORT_OPEN_PGP_KEY: - TITLE_IMPORT_OPEN_PGP_KEY: "Import OpenPGP key" - BUTTON_IMPORT_OPEN_PGP_KEY: "Import" - POPUPS_VIEW_OPEN_PGP_KEY: - TITLE_VIEW_OPEN_PGP_KEY: "View OpenPGP key" - BUTTON_SELECT: "Select" - BUTTON_CLOSE: "Close" - POPUPS_GENERATE_OPEN_PGP_KEYS: - TITLE_GENERATE_OPEN_PGP_KEYS: "Generate OpenPGP keys" - LABEL_EMAIL: "Email" - LABEL_NAME: "Name" - LABEL_PASSWORD: "Password" - LABEL_KEY_BIT_LENGTH: "Key length" - BUTTON_GENERATE_OPEN_PGP_KEYS: "Generate" - POPUPS_COMPOSE_OPEN_PGP: - TITLE_COMPOSE_OPEN_PGP: "OpenPGP Sign/Encrypt" - LABEL_SIGN: "Sign" - LABEL_ENCRYPT: "Encrypt" - LABEL_PASSWORD: "Password" - BUTTON_SIGN: "Sign" - BUTTON_ENCRYPT: "Encrypt" - BUTTON_SIGN_AND_ENCRYPT: "Sign and encrypt" - POPUPS_MESSAGE_OPEN_PGP: - TITLE_MESSAGE_OPEN_PGP: "OpenPGP Decrypt" - LABEL_KEY: "Private Key" - LABEL_PASSWORD: "Password" - BUTTON_DECRYPT: "Decrypt" - POPUPS_TWO_FACTOR_TEST: - TITLE_TEST_CODE: "2-Step verification test" - LABEL_CODE: "Code" - BUTTON_TEST: "Test" - POPUPS_FILTER: - TITLE_CREATE_FILTER: "Create a filter?" - TITLE_EDIT_FILTER: "Update filter?" - FILTER_NAME: "Name" - LEGEND_CONDITIONS: "Conditions" - LEGEND_ACTIONS: "Actions" - BUTTON_DONE: "Done" - BUTTON_ADD_CONDITION: "Add a Condition" - SELECT_ACTION_NONE: "None" - SELECT_ACTION_MOVE_TO: "Move to" - SELECT_ACTION_FORWARD_TO: "Forward to" - SELECT_ACTION_REJECT: "Reject" - SELECT_ACTION_VACATION_MESSAGE: "Vacation message" - SELECT_ACTION_DISCARD: "Discard" - SELECT_FIELD_FROM: "From" - SELECT_FIELD_RECIPIENTS: "Recipients (To or CC)" - SELECT_FIELD_SUBJECT: "Subject" - SELECT_FIELD_HEADER: "Header" - SELECT_FIELD_SIZE: "Size" - SELECT_TYPE_CONTAINS: "Contains" - SELECT_TYPE_NOT_CONTAINS: "Not Contains" - SELECT_TYPE_MATCHES: "Matches (* and ? supported)" - SELECT_TYPE_NOT_MATCHES: "Not Matches (* and ? supported)" - SELECT_TYPE_REGEXP: "Regexp" - SELECT_TYPE_NOT_REGEXP: "Not Regexp" - SELECT_TYPE_EQUAL_TO: "Equal To" - SELECT_TYPE_NOT_EQUAL_TO: "Not Equal To" - SELECT_TYPE_OVER: "Over" - SELECT_TYPE_UNDER: "Under" - SELECT_MATCH_ANY: "Matching ANY of the following rules" - SELECT_MATCH_ALL: "Matching ALL of the following rules" - MARK_AS_READ_LABEL: "Mark as read" - REPLY_INTERVAL_LABEL: "Reply interval (days)" - KEEP_LABEL: "Keep" - STOP_LABEL: "Don't stop processing rules" - EMAIL_LABEL: "Email" - VACATION_SUBJECT_LABEL: "Subject (optional)" - VACATION_MESSAGE_LABEL: "Message" - VACATION_RECIPIENTS_LABEL: "Recipients (comma separated)" - REJECT_MESSAGE_LABEL: "Reject message" - ALL_INCOMING_MESSAGES_DESC: "All incoming messages" - POPUPS_SYSTEM_FOLDERS: - TITLE_SYSTEM_FOLDERS: "Select system folders" - SELECT_CHOOSE_ONE: "Choose one" - SELECT_UNUSE_NAME: "Do not use" - LABEL_SENT: "Sent" - LABEL_DRAFTS: "Drafts" - LABEL_SPAM: "Spam" - LABEL_TRASH: "Trash" - LABEL_ARCHIVE: "Archive" - BUTTON_CANCEL: "Cancel" - BUTTON_CLOSE: "Close" + SUGGESTIONS: + SEARCHING_DESC: "Searching..." + CONTACTS: + LEGEND_CONTACTS: "Contacts" + SEARCH_INPUT_PLACEHOLDER: "Search" + BUTTON_ADD_CONTACT: "Add Contact" + BUTTON_CREATE_CONTACT: "Create" + BUTTON_UPDATE_CONTACT: "Update" + BUTTON_IMPORT: "Import (csv, vcf, vCard)" + BUTTON_EXPORT_VCARD: "Export (vcf, vCard)" + BUTTON_EXPORT_CSV: "Export (csv)" + ERROR_IMPORT_FILE: "Import error (invalid file format)" + LIST_LOADING: "Loading" + EMPTY_LIST: "No contacts here" + EMPTY_SEARCH: "No contacts found" + CLEAR_SEARCH: "Clear search" + CONTACT_VIEW_DESC: "Select contact in the list to view it here." + LABEL_DISPLAY_NAME: "Display name" + LABEL_EMAIL: "Email" + LABEL_PHONE: "Phone" + LABEL_WEB: "Web" + LABEL_BIRTHDAY: "Birthday" + LINK_ADD_EMAIL: "Add an email address" + LINK_ADD_PHONE: "Add a phone" + LINK_BIRTHDAY: "Birthday" + PLACEHOLDER_ENTER_DISPLAY_NAME: "Enter display name" + PLACEHOLDER_ENTER_LAST_NAME: "Enter last name" + PLACEHOLDER_ENTER_FIRST_NAME: "Enter first name" + PLACEHOLDER_ENTER_NICK_NAME: "Enter nickname" + LABEL_READ_ONLY: "Read only" + LABEL_SHARE: "Share" + ADD_MENU_LABEL: "Add" + ADD_MENU_NICKNAME: "Nickname" + ADD_MENU_NOTES: "Notes" + ADD_MENU_EMAIL: "Email" + ADD_MENU_PHONE: "Phone" + ADD_MENU_URL: "URL" + ADD_MENU_ADDRESS: "Address" + ADD_MENU_BIRTHDAY: "Birthday" + ADD_MENU_TAGS: "Tags" + BUTTON_SHARE_NONE: "None" + BUTTON_SHARE_ALL: "Everyone" + BUTTON_SYNC: "Synchronization (CardDAV)" + COMPOSE: + TITLE_FROM: "From" + TITLE_TO: "To" + TITLE_CC: "CC" + TITLE_BCC: "BCC" + TITLE_REPLY_TO: "Reply-To" + TITLE_SUBJECT: "Subject" + LINK_SHOW_INPUTS: "show all fields" + BUTTON_SEND: "Send" + BUTTON_SAVE: "Save" + BUTTON_DELETE: "Delete" + BUTTON_CANCEL: "Cancel" + BUTTON_MINIMIZE: "Minimize" + SAVED_TIME: "Saved at %TIME%" + SAVED_ERROR_ON_SEND: "Message was sent but not saved to sent items folder" + DISCARD_UNSAVED_DATA: "Discard unsaved data?" + ATTACH_FILES: "Attach files" + ATTACH_DROP_FILES_DESC: "Drop files here" + ATTACH_ITEM_CANCEL: "Cancel" + DROPBOX: "Dropbox" + GOOGLE_DRIVE: "Google Drive" + REPLY_MESSAGE_TITLE: "%DATETIME%, %EMAIL% wrote" + FORWARD_MESSAGE_TOP_TITLE: "-------- Forwarded message -------" + FORWARD_MESSAGE_TOP_FROM: "From" + FORWARD_MESSAGE_TOP_TO: "To" + FORWARD_MESSAGE_TOP_CC: "CC" + FORWARD_MESSAGE_TOP_SENT: "Sent" + FORWARD_MESSAGE_TOP_SUBJECT: "Subject" + EMPTY_TO_ERROR_DESC: "Please specify at least one recipient" + NO_ATTACHMENTS_HERE_DESC: "No attachments here." + ATTACHMENTS_ERROR_DESC: "Warning! Not all attachments have been uploaded." + ATTACHMENTS_UPLOAD_ERROR_DESC: "Not all attachments have been uploaded yet." + BUTTON_REQUEST_READ_RECEIPT: "Request a read receipt" + BUTTON_MARK_AS_IMPORTANT: "Mark as important" + BUTTON_OPEN_PGP: "OpenPGP (Plain Text Only)" + BUTTON_REQUEST_DSN: "Request a delivery receipt" + POPUPS_WELCOME_PAGE: + BUTTON_CLOSE: "Close" + POPUPS_ASK: + BUTTON_YES: "Yes" + BUTTON_NO: "No" + DESC_WANT_CLOSE_THIS_WINDOW: "Are you sure you want to close this window?" + DESC_WANT_DELETE_MESSAGES: "Are you sure you want to delete the message(s)?" + POPUPS_LANGUAGES: + TITLE_LANGUAGES: "Choose your language" + POPUPS_ADD_ACCOUNT: + TITLE_ADD_ACCOUNT: "Add Account?" + BUTTON_ADD_ACCOUNT: "Add" + TITLE_UPDATE_ACCOUNT: "Update Account?" + BUTTON_UPDATE_ACCOUNT: "Update" + POPUPS_IDENTITY: + TITLE_ADD_IDENTITY: "Add Identity?" + TITLE_UPDATE_IDENTITY: "Update Identity?" + BUTTON_ADD_IDENTITY: "Add" + BUTTON_UPDATE_IDENTITY: "Update" + LABEL_EMAIL: "Email" + LABEL_NAME: "Name" + LABEL_REPLY_TO: "Reply-To" + LABEL_SIGNATURE: "Signature" + LABEL_CC: "Cc" + LABEL_BCC: "Bcc" + LABEL_SIGNATURE_INSERT_BEFORE: "Insert this signature before quoted text in replies" + POPUPS_CREATE_FOLDER: + TITLE_CREATE_FOLDER: "Create a folder?" + LABEL_NAME: "Folder name" + LABEL_PARENT: "Parent folder" + BUTTON_CREATE: "Create" + BUTTON_CANCEL: "Cancel" + BUTTON_CLOSE: "Close" + TITLE_CREATING_PROCESS: "Creating a folder" + POPUPS_CLEAR_FOLDER: + TITLE_CLEAR_FOLDER: "Purge all messages from the folder?" + BUTTON_CLEAR: "Clear" + BUTTON_CANCEL: "Cancel" + BUTTON_CLOSE: "Close" + DANGER_DESC_WARNING: "Warning!" + DANGER_DESC_HTML_1: "This action will result in removing all mails from %FOLDER% folder completely." + DANGER_DESC_HTML_2: "Once started, the process cannot be aborted or cancelled." + TITLE_CLEARING_PROCESS: "Purging the folder..." + POPUPS_IMPORT_OPEN_PGP_KEY: + TITLE_IMPORT_OPEN_PGP_KEY: "Import OpenPGP key" + BUTTON_IMPORT_OPEN_PGP_KEY: "Import" + POPUPS_VIEW_OPEN_PGP_KEY: + TITLE_VIEW_OPEN_PGP_KEY: "View OpenPGP key" + BUTTON_SELECT: "Select" + BUTTON_CLOSE: "Close" + POPUPS_GENERATE_OPEN_PGP_KEYS: + TITLE_GENERATE_OPEN_PGP_KEYS: "Generate OpenPGP keys" + LABEL_EMAIL: "Email" + LABEL_NAME: "Name" + LABEL_PASSWORD: "Password" + LABEL_KEY_BIT_LENGTH: "Key length" + BUTTON_GENERATE_OPEN_PGP_KEYS: "Generate" + POPUPS_COMPOSE_OPEN_PGP: + TITLE_COMPOSE_OPEN_PGP: "OpenPGP Sign/Encrypt" + LABEL_SIGN: "Sign" + LABEL_ENCRYPT: "Encrypt" + LABEL_PASSWORD: "Password" + BUTTON_SIGN: "Sign" + BUTTON_ENCRYPT: "Encrypt" + BUTTON_SIGN_AND_ENCRYPT: "Sign and encrypt" + POPUPS_MESSAGE_OPEN_PGP: + TITLE_MESSAGE_OPEN_PGP: "OpenPGP Decrypt" + LABEL_KEY: "Private Key" + LABEL_PASSWORD: "Password" + BUTTON_DECRYPT: "Decrypt" + POPUPS_TWO_FACTOR_TEST: + TITLE_TEST_CODE: "2-Step verification test" + LABEL_CODE: "Code" + BUTTON_TEST: "Test" + POPUPS_FILTER: + TITLE_CREATE_FILTER: "Create a filter?" + TITLE_EDIT_FILTER: "Update filter?" + FILTER_NAME: "Name" + LEGEND_CONDITIONS: "Conditions" + LEGEND_ACTIONS: "Actions" + BUTTON_DONE: "Done" + BUTTON_ADD_CONDITION: "Add a Condition" + SELECT_ACTION_NONE: "None" + SELECT_ACTION_MOVE_TO: "Move to" + SELECT_ACTION_FORWARD_TO: "Forward to" + SELECT_ACTION_REJECT: "Reject" + SELECT_ACTION_VACATION_MESSAGE: "Vacation message" + SELECT_ACTION_DISCARD: "Discard" + SELECT_FIELD_FROM: "From" + SELECT_FIELD_RECIPIENTS: "Recipients (To or CC)" + SELECT_FIELD_SUBJECT: "Subject" + SELECT_FIELD_HEADER: "Header" + SELECT_FIELD_SIZE: "Size" + SELECT_TYPE_CONTAINS: "Contains" + SELECT_TYPE_NOT_CONTAINS: "Not Contains" + SELECT_TYPE_MATCHES: "Matches (* and ? supported)" + SELECT_TYPE_NOT_MATCHES: "Not Matches (* and ? supported)" + SELECT_TYPE_REGEXP: "Regexp" + SELECT_TYPE_NOT_REGEXP: "Not Regexp" + SELECT_TYPE_EQUAL_TO: "Equal To" + SELECT_TYPE_NOT_EQUAL_TO: "Not Equal To" + SELECT_TYPE_OVER: "Over" + SELECT_TYPE_UNDER: "Under" + SELECT_MATCH_ANY: "Matching ANY of the following rules" + SELECT_MATCH_ALL: "Matching ALL of the following rules" + MARK_AS_READ_LABEL: "Mark as read" + REPLY_INTERVAL_LABEL: "Reply interval (days)" + KEEP_LABEL: "Keep" + STOP_LABEL: "Don't stop processing rules" + EMAIL_LABEL: "Email" + VACATION_SUBJECT_LABEL: "Subject (optional)" + VACATION_MESSAGE_LABEL: "Message" + VACATION_RECIPIENTS_LABEL: "Recipients (comma separated)" + REJECT_MESSAGE_LABEL: "Reject message" + ALL_INCOMING_MESSAGES_DESC: "All incoming messages" + POPUPS_SYSTEM_FOLDERS: + TITLE_SYSTEM_FOLDERS: "Select system folders" + SELECT_CHOOSE_ONE: "Choose one" + SELECT_UNUSE_NAME: "Do not use" + LABEL_SENT: "Sent" + LABEL_DRAFTS: "Drafts" + LABEL_SPAM: "Spam" + LABEL_TRASH: "Trash" + LABEL_ARCHIVE: "Archive" + BUTTON_CANCEL: "Cancel" + BUTTON_CLOSE: "Close" NOTIFICATION_SENT: | You haven't selected "Sent" system folder messages are put to after sending. If you don't want to save sent message, please select "Do not use" option. - NOTIFICATION_DRAFTS: "You haven't selected \"Drafts\" system folder messages are saved to while composing." + NOTIFICATION_DRAFTS: "You haven't selected \"Drafts\" system folder messages are saved to while composing." NOTIFICATION_SPAM: | You haven't selected "Spam" system folder spamed messages are placed to. If you wish to remove messages permanently, please select "Do not use" option. NOTIFICATION_TRASH: | You haven't selected "Trash" system folder deleted messages are placed to. If you wish to remove messages permanently, please select "Do not use" option. - NOTIFICATION_ARCHIVE: "You haven't selected \"Archive\" system folder achived messages are placed to." - POPUPS_TWO_FACTOR_CFG: - LEGEND_TWO_FACTOR_AUTH: "2-Step Verification (TOTP)" - LABEL_ENABLE_TWO_FACTOR: "Enable 2-Step verification" - LABEL_TWO_FACTOR_USER: "User" - LABEL_TWO_FACTOR_STATUS: "Status" - LABEL_TWO_FACTOR_SECRET: "Secret" - LABEL_TWO_FACTOR_BACKUP_CODES: "Backup codes" - BUTTON_CREATE: "Create a secret" - BUTTON_ACTIVATE: "Activate" - BUTTON_CLEAR: "Clear" - BUTTON_LOGOUT: "Logout" - BUTTON_DONE: "Done" - BUTTON_TEST: "Test" - LINK_TEST: "test" - BUTTON_SHOW_SECRET: "Show Secret" - BUTTON_HIDE_SECRET: "Hide Secret" - TWO_FACTOR_REQUIRE_DESC: "Your account requires 2-Step verification configuration." - TWO_FACTOR_SECRET_CONFIGURED_DESC: "Configured" - TWO_FACTOR_SECRET_NOT_CONFIGURED_DESC: "Not configured" + NOTIFICATION_ARCHIVE: "You haven't selected \"Archive\" system folder achived messages are placed to." + POPUPS_TWO_FACTOR_CFG: + LEGEND_TWO_FACTOR_AUTH: "2-Step Verification (TOTP)" + LABEL_ENABLE_TWO_FACTOR: "Enable 2-Step verification" + LABEL_TWO_FACTOR_USER: "User" + LABEL_TWO_FACTOR_STATUS: "Status" + LABEL_TWO_FACTOR_SECRET: "Secret" + LABEL_TWO_FACTOR_BACKUP_CODES: "Backup codes" + BUTTON_CREATE: "Create a secret" + BUTTON_ACTIVATE: "Activate" + BUTTON_CLEAR: "Clear" + BUTTON_LOGOUT: "Logout" + BUTTON_DONE: "Done" + BUTTON_TEST: "Test" + LINK_TEST: "test" + BUTTON_SHOW_SECRET: "Show Secret" + BUTTON_HIDE_SECRET: "Hide Secret" + TWO_FACTOR_REQUIRE_DESC: "Your account requires 2-Step verification configuration." + TWO_FACTOR_SECRET_CONFIGURED_DESC: "Configured" + TWO_FACTOR_SECRET_NOT_CONFIGURED_DESC: "Not configured" TWO_FACTOR_SECRET_DESC: > Import this info into your Google Authenticator client (or other TOTP client) using the provided QR code below or by entering the code manually. @@ -402,246 +402,246 @@ en: If you can't receive codes via Google Authenticator (or other TOTP client), you can use backup codes to sign in. After you’ve used a backup code to sign in, it will become inactive. - TWO_FACTOR_SECRET_TEST_BEFORE_DESC: "You can't change this setting before test." - TITLES: - LOADING: "Loading" - LOGIN: "Login" - MAILBOX: "MailBox" - SETTINGS: "Settings" - COMPOSE: "Compose" - UPLOAD: - ERROR_FILE_IS_TOO_BIG: "File is too big" - ERROR_FILE_PARTIALLY_UPLOADED: "File was partially uploaded due to unknown error" - ERROR_NO_FILE_UPLOADED: "No file uploaded" - ERROR_MISSING_TEMP_FOLDER: "The temporary file is missing" - ERROR_ON_SAVING_FILE: "An unknown file upload error occurred" - ERROR_FILE_TYPE: "Invalid file type" - ERROR_UNKNOWN: "An unknown file upload error occurred" - EDITOR: - TEXT_SWITCHER_PLAINT_TEXT: "HTML <-> TEXT" - TEXT_SWITCHER_RICH_FORMATTING: "Rich formatting" - TEXT_SWITCHER_CONFIRM: "Text formatting and images will be lost. Are you sure you want to continue?" - SETTINGS_LABELS: - LABEL_PERSONAL_NAME: "Personal" - LABEL_GENERAL_NAME: "General" - LABEL_CONTACTS_NAME: "Contacts" - LABEL_FOLDERS_NAME: "Folders" - LABEL_ACCOUNTS_NAME: "Accounts" - LABEL_IDENTITY_NAME: "Identity" - LABEL_IDENTITIES_NAME: "Identities" - LABEL_FILTERS_NAME: "Filters" - LABEL_TEMPLATES_NAME: "Templates" - LABEL_SECURITY_NAME: "Security" - LABEL_SOCIAL_NAME: "Social" - LABEL_THEMES_NAME: "Themes" - LABEL_CHANGE_PASSWORD_NAME: "Password" - LABEL_OPEN_PGP_NAME: "OpenPGP" - BUTTON_BACK: "Back" - SETTINGS_FILTERS: - LEGEND_FILTERS: "Filters" - BUTTON_SAVE: "Save" - BUTTON_ADD_FILTER: "Add a Filter" - BUTTON_DELETE: "Delete" - BUTTON_RAW_SCRIPT: "Use Custom User Script" - SUBNAME_NONE: "None" - SUBNAME_MOVE_TO: "Move to \"%FOLDER%\"" - SUBNAME_FORWARD_TO: "Forward to \"%EMAIL%\"" - SUBNAME_REJECT: "Reject" - SUBNAME_VACATION_MESSAGE: "Vacation message" - SUBNAME_DISCARD: "Discard" - CAPABILITY_LABEL: "Capability" - LOADING_PROCESS: "Updating filter list" - DELETING_ASK: "Are you sure?" - CHACHES_NEED_TO_BE_SAVED_DESC: "These changes need to be saved to the server." - SETTINGS_IDENTITY: - LEGEND_IDENTITY: "Identity" - LABEL_DISPLAY_NAME: "Name" - LABEL_REPLY_TO: "Reply-To" - LABEL_SIGNATURE: "Signature" - LABEL_ADD_SIGNATURE_TO_ALL: "Add your signature to all the outgoing messages" - SETTINGS_SECURITY: - LEGEND_SECURITY: "Security" - LABEL_CONFIGURE_TWO_FACTOR: "Configure 2-Step verification" - LABEL_AUTOLOGOUT: "Auto Logout" - AUTOLOGIN_NEVER_OPTION_NAME: "Never" - AUTOLOGIN_MINUTES_OPTION_NAME: "%MINUTES% minute(s)" - AUTOLOGIN_HOURS_OPTION_NAME: "%HOURS% hour(s)" - SETTINGS_GENERAL: - LEGEND_GENERAL: "General" - LABEL_LANGUAGE: "Language" - LABEL_IDENTITY: "Identity" - LABEL_LAYOUT: "Layout" - LABEL_LAYOUT_NO_SPLIT: "No Split" - LABEL_LAYOUT_VERTICAL_SPLIT: "Vertical Split" - LABEL_LAYOUT_HORIZONTAL_SPLIT: "Horizontal Split" - LABEL_EDITOR: "Default text editor" - LABEL_EDITOR_HTML: "Html" - LABEL_EDITOR_PLAIN: "Plain" - LABEL_EDITOR_HTML_FORCED: "Html (forced)" - LABEL_EDITOR_PLAIN_FORCED: "Plain (forced)" - LABEL_ANIMATION: "Interface animation" - LABEL_ANIMATION_FULL: "Full" - LABEL_ANIMATION_NORMAL: "Normal" - LABEL_ANIMATION_NONE: "None" - LABEL_VIEW_OPTIONS: "View options" - LABEL_USE_PREVIEW_PANE: "Use preview pane" - LABEL_USE_CHECKBOXES_IN_LIST: "Display checkboxes in list" - LABEL_USE_THREADS: "Use threads" - LABEL_REPLY_SAME_FOLDER: "Place replies in the folder of the message being replied to" - LABEL_SHOW_IMAGES: "Always display external images in message body" - LABEL_SHOW_ANIMATION: "Show animation" - LABEL_MESSAGE_PER_PAGE: "Messages on page" - LABEL_NOTIFICATIONS: "Notifications" - LABEL_SOUND_NOTIFICATION: "Sound notification" - LABEL_CHROME_NOTIFICATION_DESC: "Show new messages notification popups" - LABEL_CHROME_NOTIFICATION_DESC_DENIED: "(Blocked by the browser)" - SETTINGS_CONTACTS: - LEGEND_CONTACTS: "Contacts" - LABEL_CONTACTS_AUTOSAVE: "Automatically add recipients to your address book" - LEGEND_CONTACTS_SYNC: "Remote Synchronization (CardDAV)" - LABEL_CONTACTS_SYNC_ENABLE: "Enable remote synchronization" - LABEL_CONTACTS_SYNC_SERVER: "Server" - LABEL_CONTACTS_SYNC_AB_URL: "Addressbook URL" - LABEL_CONTACTS_SYNC_USER: "User" - LABEL_CONTACTS_SYNC_PASSWORD: "Password" - SETTINGS_THEMES: - LEGEND_THEMES: "Themes" - LEGEND_THEMES_CUSTOM: "Custom Theme Configuration" - LABEL_CUSTOM_TYPE: "Type" - LABEL_CUSTOM_TYPE_LIGHT: "Light" - LABEL_CUSTOM_TYPE_DARK: "Dark" - LABEL_CUSTOM_BACKGROUND_IMAGE: "Background" - BUTTON_UPLOAD_BACKGROUND_IMAGE: "Upload background image (JPG, PNG)" - ERROR_FILE_IS_TOO_BIG: "File is too big" - ERROR_FILE_TYPE_ERROR: "Invalid file type (JPG and PNG only)" - ERROR_UNKNOWN: "An unknown file upload error occurred" - SETTINGS_SOCIAL: - LEGEND_GOOGLE: "Google" - BUTTON_GOOGLE_CONNECT: "Connect Google" - BUTTON_GOOGLE_DISCONNECT: "Disconnect Google" - MAIN_GOOGLE_DESC: "After enabling login via Google, you can log into this account using Google button on the login screen." - LEGEND_FACEBOOK: "Facebook" - BUTTON_FACEBOOK_CONNECT: "Connect Facebook" - BUTTON_FACEBOOK_DISCONNECT: "Disconnect Facebook" - MAIN_FACEBOOK_DESC: "After enabling login via Facebook, you can log into this account using Facebook button on the login screen." - LEGEND_TWITTER: "Twitter" - BUTTON_TWITTER_CONNECT: "Connect Twitter" - BUTTON_TWITTER_DISCONNECT: "Disconnect Twitter" - MAIN_TWITTER_DESC: "After enabling login via Twitter, you can log into this account using Twitter button on the login screen." - SETTINGS_FOLDERS: - LEGEND_FOLDERS: "Folder List" - BUTTON_CREATE: "Create Folder" - BUTTON_SYSTEM: "System Folders" - BUTTON_DELETE: "Delete" - BUTTON_SUBSCRIBE: "Subscribe" - BUTTON_UNSUBSCRIBE: "Unsubscribe" - LOADING_PROCESS: "Updating folder list" - CREATING_PROCESS: "Creating a folder" - DELETING_PROCESS: "Deleting a folder" - RENAMING_PROCESS: "Renaming a folder" - DELETING_ASK: "Are you sure?" - TO_MANY_FOLDERS_DESC_1: "You have too many folders!" - TO_MANY_FOLDERS_DESC_2: "We have shown only a part of them, to avoid performance problems." - HELP_DELETE_FOLDER: "Delete folder" - HELP_SHOW_HIDE_FOLDER: "Show/hide folder" - HELP_CHECK_FOR_NEW_MESSAGES: "Check/don't check for new messages" - SETTINGS_ACCOUNTS: - LEGEND_ACCOUNTS: "Accounts" - LEGEND_IDENTITIES: "Identities" - LEGEND_ACCOUNTS_AND_IDENTITIES: "Accounts and Identities" - BUTTON_ADD_ACCOUNT: "Add an Account" - BUTTON_ADD_IDENTITY: "Add an Identity" - BUTTON_DELETE: "Delete" - LOADING_PROCESS: "Updating..." - DELETING_ASK: "Are you sure?" - DEFAULT_IDENTITY_LABEL: "default" - SETTINGS_IDENTITIES: - LEGEND_IDENTITY: "Identity" - LEGEND_IDENTITIES: "Additional Identities" - LABEL_DEFAULT: "Default" - LABEL_DISPLAY_NAME: "Name" - LABEL_REPLY_TO: "Reply-To" - LABEL_SIGNATURE: "Signature" - LABEL_ADD_SIGNATURE_TO_ALL: "Add your signature to all the outgoing messages" - BUTTON_ADD_IDENTITY: "Add Identity" - BUTTON_DELETE: "Delete" - LOADING_PROCESS: "Updating identity list" - DELETING_ASK: "Are you sure?" - SETTINGS_CHANGE_PASSWORD: - LEGEND_CHANGE_PASSWORD: "Change Password" - LABEL_CURRENT_PASSWORD: "Current password" - LABEL_NEW_PASSWORD: "New password" - LABEL_REPEAT_PASSWORD: "Confirm New Password" - BUTTON_UPDATE_PASSWORD: "Set New Password" - ERROR_PASSWORD_MISMATCH: "Passwords do not match, please try again" - SETTINGS_OPEN_PGP: - LEGEND_OPEN_PGP: "OpenPGP" - BUTTON_ADD_OPEN_PGP_KEY: "Import OpenPGP Key" - BUTTON_GENERATE_OPEN_PGP_KEYS: "Generate OpenPGP Keys" - TITLE_PRIVATE: "Private" - TITLE_PUBLIC: "Public" - DELETING_ASK: "Are you sure?" - GENERATE_ONLY_HTTPS: "HTTPS only" - LABEL_ALLOW_DRAFT_AUTOSAVE: "Automatically save draft" - SHORTCUTS_HELP: - LEGEND_SHORTCUTS_HELP: "Keyboard shortcuts help" - TAB_MAILBOX: "Mailbox" - TAB_MESSAGE_LIST: "Message list" - TAB_MESSAGE_VIEW: "Message view" - TAB_COMPOSE: "Compose" - LABEL_OPEN_USER_DROPDOWN: "Open user dropdown" - LABEL_REPLY: "Reply" - LABEL_REPLY_ALL: "Reply All" - LABEL_FORWARD: "Forward" - LABEL_FORWARD_MULTIPLY: "Forward as attachment(s)" - LABEL_HELP: "Help" - LABEL_CHECK_ALL: "Select all messages" - LABEL_ARCHIVE: "Archive" - LABEL_DELETE: "Delete" - LABEL_OPEN_THREAD: "Open selected thread" - LABEL_MOVE: "Move" - LABEL_READ: "Read selected messages" - LABEL_UNREAD: "Unread selected messages" - LABEL_IMPORTANT: "Important, flag selected messages" - LABEL_SEARCH: "Search" - LABEL_CANCEL_SEARCH: "Cancel search" - LABEL_FULLSCREEN_ENTER: "Fullscreen (Preview pane layout)" - LABEL_VIEW_MESSAGE_ENTER: "View message (No preview pane layout)" - LABEL_SWITCH_TO_MESSAGE: "Switch focus to selected message" - LABEL_SWITCH_TO_FOLDER_LIST: "Switch focus to folder list" - LABEL_FULLSCREEN_TOGGLE: "Toggle fullscreen mode" - LABEL_BLOCKQUOTES_TOGGLE: "Toggle message blockquotes" - LABEL_THREAD_NEXT: "Next message in thread" - LABEL_THREAD_PREV: "Previous message in thread" - LABEL_PRINT: "Print" - LABEL_EXIT_FULLSCREEN: "Exit fullscreen mode" - LABEL_CLOSE_MESSAGE: "Close message (No preview pane layout)" - LABEL_SWITCH_TO_LIST: "Switch focus back to message list" - LABEL_OPEN_COMPOSE_POPUP: "Open compose popup" - LABEL_MINIMIZE_COMPOSE_POPUP: "Minimize compose popup" - LABEL_OPEN_IDENTITIES_DROPDOWN: "Open identities dropdown" - LABEL_SAVE_MESSAGE: "Save message" - LABEL_SEND_MESSAGE: "Send message" - LABEL_CLOSE_COMPOSE: "Close compose" - PGP_NOTIFICATIONS: - NO_PUBLIC_KEYS_FOUND: "No public keys found" - NO_PUBLIC_KEYS_FOUND_FOR: "No public keys found for \"%EMAIL%\" email" - NO_PRIVATE_KEY_FOUND: "No private key found" - NO_PRIVATE_KEY_FOUND_FOR: "No private key found for \"%EMAIL%\" email" - ADD_A_PUBLICK_KEY: "Add a public key" - SELECT_A_PRIVATE_KEY: "Select a private key" - UNVERIFIRED_SIGNATURE: "Unverified signature" - DECRYPTION_ERROR: "OpenPGP decryption error" - GOOD_SIGNATURE: "Good signature from %USER%" - PGP_ERROR: "OpenPGP error: %ERROR%" - SPECIFY_FROM_EMAIL: "Please specify FROM email address" - SPECIFY_AT_LEAST_ONE_RECIPIENT: "Please specify at least one recipient" - NOTIFICATIONS: - INVALID_TOKEN: "Invalid token" - AUTH_ERROR: "Authentication failed" - ACCESS_ERROR: "Access error" - CONNECTION_ERROR: "Can't connect to server" - CAPTCHA_ERROR: "Incorrect CAPTCHA." + TWO_FACTOR_SECRET_TEST_BEFORE_DESC: "You can't change this setting before test." + TITLES: + LOADING: "Loading" + LOGIN: "Login" + MAILBOX: "MailBox" + SETTINGS: "Settings" + COMPOSE: "Compose" + UPLOAD: + ERROR_FILE_IS_TOO_BIG: "File is too big" + ERROR_FILE_PARTIALLY_UPLOADED: "File was partially uploaded due to unknown error" + ERROR_NO_FILE_UPLOADED: "No file uploaded" + ERROR_MISSING_TEMP_FOLDER: "The temporary file is missing" + ERROR_ON_SAVING_FILE: "An unknown file upload error occurred" + ERROR_FILE_TYPE: "Invalid file type" + ERROR_UNKNOWN: "An unknown file upload error occurred" + EDITOR: + TEXT_SWITCHER_PLAINT_TEXT: "HTML <-> TEXT" + TEXT_SWITCHER_RICH_FORMATTING: "Rich formatting" + TEXT_SWITCHER_CONFIRM: "Text formatting and images will be lost. Are you sure you want to continue?" + SETTINGS_LABELS: + LABEL_PERSONAL_NAME: "Personal" + LABEL_GENERAL_NAME: "General" + LABEL_CONTACTS_NAME: "Contacts" + LABEL_FOLDERS_NAME: "Folders" + LABEL_ACCOUNTS_NAME: "Accounts" + LABEL_IDENTITY_NAME: "Identity" + LABEL_IDENTITIES_NAME: "Identities" + LABEL_FILTERS_NAME: "Filters" + LABEL_TEMPLATES_NAME: "Templates" + LABEL_SECURITY_NAME: "Security" + LABEL_SOCIAL_NAME: "Social" + LABEL_THEMES_NAME: "Themes" + LABEL_CHANGE_PASSWORD_NAME: "Password" + LABEL_OPEN_PGP_NAME: "OpenPGP" + BUTTON_BACK: "Back" + SETTINGS_FILTERS: + LEGEND_FILTERS: "Filters" + BUTTON_SAVE: "Save" + BUTTON_ADD_FILTER: "Add a Filter" + BUTTON_DELETE: "Delete" + BUTTON_RAW_SCRIPT: "Use Custom User Script" + SUBNAME_NONE: "None" + SUBNAME_MOVE_TO: "Move to \"%FOLDER%\"" + SUBNAME_FORWARD_TO: "Forward to \"%EMAIL%\"" + SUBNAME_REJECT: "Reject" + SUBNAME_VACATION_MESSAGE: "Vacation message" + SUBNAME_DISCARD: "Discard" + CAPABILITY_LABEL: "Capability" + LOADING_PROCESS: "Updating filter list" + DELETING_ASK: "Are you sure?" + CHACHES_NEED_TO_BE_SAVED_DESC: "These changes need to be saved to the server." + SETTINGS_IDENTITY: + LEGEND_IDENTITY: "Identity" + LABEL_DISPLAY_NAME: "Name" + LABEL_REPLY_TO: "Reply-To" + LABEL_SIGNATURE: "Signature" + LABEL_ADD_SIGNATURE_TO_ALL: "Add your signature to all the outgoing messages" + SETTINGS_SECURITY: + LEGEND_SECURITY: "Security" + LABEL_CONFIGURE_TWO_FACTOR: "Configure 2-Step verification" + LABEL_AUTOLOGOUT: "Auto Logout" + AUTOLOGIN_NEVER_OPTION_NAME: "Never" + AUTOLOGIN_MINUTES_OPTION_NAME: "%MINUTES% minute(s)" + AUTOLOGIN_HOURS_OPTION_NAME: "%HOURS% hour(s)" + SETTINGS_GENERAL: + LEGEND_GENERAL: "General" + LABEL_LANGUAGE: "Language" + LABEL_IDENTITY: "Identity" + LABEL_LAYOUT: "Layout" + LABEL_LAYOUT_NO_SPLIT: "No Split" + LABEL_LAYOUT_VERTICAL_SPLIT: "Vertical Split" + LABEL_LAYOUT_HORIZONTAL_SPLIT: "Horizontal Split" + LABEL_EDITOR: "Default text editor" + LABEL_EDITOR_HTML: "Html" + LABEL_EDITOR_PLAIN: "Plain" + LABEL_EDITOR_HTML_FORCED: "Html (forced)" + LABEL_EDITOR_PLAIN_FORCED: "Plain (forced)" + LABEL_ANIMATION: "Interface animation" + LABEL_ANIMATION_FULL: "Full" + LABEL_ANIMATION_NORMAL: "Normal" + LABEL_ANIMATION_NONE: "None" + LABEL_VIEW_OPTIONS: "View options" + LABEL_USE_PREVIEW_PANE: "Use preview pane" + LABEL_USE_CHECKBOXES_IN_LIST: "Display checkboxes in list" + LABEL_USE_THREADS: "Use threads" + LABEL_REPLY_SAME_FOLDER: "Place replies in the folder of the message being replied to" + LABEL_SHOW_IMAGES: "Always display external images in message body" + LABEL_SHOW_ANIMATION: "Show animation" + LABEL_MESSAGE_PER_PAGE: "Messages on page" + LABEL_NOTIFICATIONS: "Notifications" + LABEL_SOUND_NOTIFICATION: "Sound notification" + LABEL_CHROME_NOTIFICATION_DESC: "Show new messages notification popups" + LABEL_CHROME_NOTIFICATION_DESC_DENIED: "(Blocked by the browser)" + SETTINGS_CONTACTS: + LEGEND_CONTACTS: "Contacts" + LABEL_CONTACTS_AUTOSAVE: "Automatically add recipients to your address book" + LEGEND_CONTACTS_SYNC: "Remote Synchronization (CardDAV)" + LABEL_CONTACTS_SYNC_ENABLE: "Enable remote synchronization" + LABEL_CONTACTS_SYNC_SERVER: "Server" + LABEL_CONTACTS_SYNC_AB_URL: "Addressbook URL" + LABEL_CONTACTS_SYNC_USER: "User" + LABEL_CONTACTS_SYNC_PASSWORD: "Password" + SETTINGS_THEMES: + LEGEND_THEMES: "Themes" + LEGEND_THEMES_CUSTOM: "Custom Theme Configuration" + LABEL_CUSTOM_TYPE: "Type" + LABEL_CUSTOM_TYPE_LIGHT: "Light" + LABEL_CUSTOM_TYPE_DARK: "Dark" + LABEL_CUSTOM_BACKGROUND_IMAGE: "Background" + BUTTON_UPLOAD_BACKGROUND_IMAGE: "Upload background image (JPG, PNG)" + ERROR_FILE_IS_TOO_BIG: "File is too big" + ERROR_FILE_TYPE_ERROR: "Invalid file type (JPG and PNG only)" + ERROR_UNKNOWN: "An unknown file upload error occurred" + SETTINGS_SOCIAL: + LEGEND_GOOGLE: "Google" + BUTTON_GOOGLE_CONNECT: "Connect Google" + BUTTON_GOOGLE_DISCONNECT: "Disconnect Google" + MAIN_GOOGLE_DESC: "After enabling login via Google, you can log into this account using Google button on the login screen." + LEGEND_FACEBOOK: "Facebook" + BUTTON_FACEBOOK_CONNECT: "Connect Facebook" + BUTTON_FACEBOOK_DISCONNECT: "Disconnect Facebook" + MAIN_FACEBOOK_DESC: "After enabling login via Facebook, you can log into this account using Facebook button on the login screen." + LEGEND_TWITTER: "Twitter" + BUTTON_TWITTER_CONNECT: "Connect Twitter" + BUTTON_TWITTER_DISCONNECT: "Disconnect Twitter" + MAIN_TWITTER_DESC: "After enabling login via Twitter, you can log into this account using Twitter button on the login screen." + SETTINGS_FOLDERS: + LEGEND_FOLDERS: "Folder List" + BUTTON_CREATE: "Create Folder" + BUTTON_SYSTEM: "System Folders" + BUTTON_DELETE: "Delete" + BUTTON_SUBSCRIBE: "Subscribe" + BUTTON_UNSUBSCRIBE: "Unsubscribe" + LOADING_PROCESS: "Updating folder list" + CREATING_PROCESS: "Creating a folder" + DELETING_PROCESS: "Deleting a folder" + RENAMING_PROCESS: "Renaming a folder" + DELETING_ASK: "Are you sure?" + TO_MANY_FOLDERS_DESC_1: "You have too many folders!" + TO_MANY_FOLDERS_DESC_2: "We have shown only a part of them, to avoid performance problems." + HELP_DELETE_FOLDER: "Delete folder" + HELP_SHOW_HIDE_FOLDER: "Show/hide folder" + HELP_CHECK_FOR_NEW_MESSAGES: "Check/don't check for new messages" + SETTINGS_ACCOUNTS: + LEGEND_ACCOUNTS: "Accounts" + LEGEND_IDENTITIES: "Identities" + LEGEND_ACCOUNTS_AND_IDENTITIES: "Accounts and Identities" + BUTTON_ADD_ACCOUNT: "Add an Account" + BUTTON_ADD_IDENTITY: "Add an Identity" + BUTTON_DELETE: "Delete" + LOADING_PROCESS: "Updating..." + DELETING_ASK: "Are you sure?" + DEFAULT_IDENTITY_LABEL: "default" + SETTINGS_IDENTITIES: + LEGEND_IDENTITY: "Identity" + LEGEND_IDENTITIES: "Additional Identities" + LABEL_DEFAULT: "Default" + LABEL_DISPLAY_NAME: "Name" + LABEL_REPLY_TO: "Reply-To" + LABEL_SIGNATURE: "Signature" + LABEL_ADD_SIGNATURE_TO_ALL: "Add your signature to all the outgoing messages" + BUTTON_ADD_IDENTITY: "Add Identity" + BUTTON_DELETE: "Delete" + LOADING_PROCESS: "Updating identity list" + DELETING_ASK: "Are you sure?" + SETTINGS_CHANGE_PASSWORD: + LEGEND_CHANGE_PASSWORD: "Change Password" + LABEL_CURRENT_PASSWORD: "Current password" + LABEL_NEW_PASSWORD: "New password" + LABEL_REPEAT_PASSWORD: "Confirm New Password" + BUTTON_UPDATE_PASSWORD: "Set New Password" + ERROR_PASSWORD_MISMATCH: "Passwords do not match, please try again" + SETTINGS_OPEN_PGP: + LEGEND_OPEN_PGP: "OpenPGP" + BUTTON_ADD_OPEN_PGP_KEY: "Import OpenPGP Key" + BUTTON_GENERATE_OPEN_PGP_KEYS: "Generate OpenPGP Keys" + TITLE_PRIVATE: "Private" + TITLE_PUBLIC: "Public" + DELETING_ASK: "Are you sure?" + GENERATE_ONLY_HTTPS: "HTTPS only" + LABEL_ALLOW_DRAFT_AUTOSAVE: "Automatically save draft" + SHORTCUTS_HELP: + LEGEND_SHORTCUTS_HELP: "Keyboard shortcuts help" + TAB_MAILBOX: "Mailbox" + TAB_MESSAGE_LIST: "Message list" + TAB_MESSAGE_VIEW: "Message view" + TAB_COMPOSE: "Compose" + LABEL_OPEN_USER_DROPDOWN: "Open user dropdown" + LABEL_REPLY: "Reply" + LABEL_REPLY_ALL: "Reply All" + LABEL_FORWARD: "Forward" + LABEL_FORWARD_MULTIPLY: "Forward as attachment(s)" + LABEL_HELP: "Help" + LABEL_CHECK_ALL: "Select all messages" + LABEL_ARCHIVE: "Archive" + LABEL_DELETE: "Delete" + LABEL_OPEN_THREAD: "Open selected thread" + LABEL_MOVE: "Move" + LABEL_READ: "Read selected messages" + LABEL_UNREAD: "Unread selected messages" + LABEL_IMPORTANT: "Important, flag selected messages" + LABEL_SEARCH: "Search" + LABEL_CANCEL_SEARCH: "Cancel search" + LABEL_FULLSCREEN_ENTER: "Fullscreen (Preview pane layout)" + LABEL_VIEW_MESSAGE_ENTER: "View message (No preview pane layout)" + LABEL_SWITCH_TO_MESSAGE: "Switch focus to selected message" + LABEL_SWITCH_TO_FOLDER_LIST: "Switch focus to folder list" + LABEL_FULLSCREEN_TOGGLE: "Toggle fullscreen mode" + LABEL_BLOCKQUOTES_TOGGLE: "Toggle message blockquotes" + LABEL_THREAD_NEXT: "Next message in thread" + LABEL_THREAD_PREV: "Previous message in thread" + LABEL_PRINT: "Print" + LABEL_EXIT_FULLSCREEN: "Exit fullscreen mode" + LABEL_CLOSE_MESSAGE: "Close message (No preview pane layout)" + LABEL_SWITCH_TO_LIST: "Switch focus back to message list" + LABEL_OPEN_COMPOSE_POPUP: "Open compose popup" + LABEL_MINIMIZE_COMPOSE_POPUP: "Minimize compose popup" + LABEL_OPEN_IDENTITIES_DROPDOWN: "Open identities dropdown" + LABEL_SAVE_MESSAGE: "Save message" + LABEL_SEND_MESSAGE: "Send message" + LABEL_CLOSE_COMPOSE: "Close compose" + PGP_NOTIFICATIONS: + NO_PUBLIC_KEYS_FOUND: "No public keys found" + NO_PUBLIC_KEYS_FOUND_FOR: "No public keys found for \"%EMAIL%\" email" + NO_PRIVATE_KEY_FOUND: "No private key found" + NO_PRIVATE_KEY_FOUND_FOR: "No private key found for \"%EMAIL%\" email" + ADD_A_PUBLICK_KEY: "Add a public key" + SELECT_A_PRIVATE_KEY: "Select a private key" + UNVERIFIRED_SIGNATURE: "Unverified signature" + DECRYPTION_ERROR: "OpenPGP decryption error" + GOOD_SIGNATURE: "Good signature from %USER%" + PGP_ERROR: "OpenPGP error: %ERROR%" + SPECIFY_FROM_EMAIL: "Please specify FROM email address" + SPECIFY_AT_LEAST_ONE_RECIPIENT: "Please specify at least one recipient" + NOTIFICATIONS: + INVALID_TOKEN: "Invalid token" + AUTH_ERROR: "Authentication failed" + ACCESS_ERROR: "Access error" + CONNECTION_ERROR: "Can't connect to server" + CAPTCHA_ERROR: "Incorrect CAPTCHA." SOCIAL_FACEBOOK_LOGIN_ACCESS_DISABLE: > This social ID is not assigned for any email account yet. Log in using email credentials and enable this feature in account settings. @@ -651,63 +651,63 @@ en: SOCIAL_GOOGLE_LOGIN_ACCESS_DISABLE: > This social ID is not assigned for any email account yet. Log in using email credentials and enable this feature in account settings. - DOMAIN_NOT_ALLOWED: "Domain is not allowed" - ACCOUNT_NOT_ALLOWED: "Account is not allowed" - ACCOUNT_TWO_FACTOR_AUTH_REQUIRED: "Two factor verification required" - ACCOUNT_TWO_FACTOR_AUTH_ERROR: "Two factor verification error" - COULD_NOT_SAVE_NEW_PASSWORD: "Could not save new password" - CURRENT_PASSWORD_INCORRECT: "Current password incorrect" - NEW_PASSWORD_SHORT: "Password is too short" - NEW_PASSWORD_WEAK: "Password is too easy" - NEW_PASSWORD_FORBIDDENT: "Password contains forbidden characters" - CONTACTS_SYNC_ERROR: "Contacts synchronization error" - CANT_GET_MESSAGE_LIST: "Can't get message list" - CANT_GET_MESSAGE: "Can't get message" - CANT_DELETE_MESSAGE: "Can't delete message" - CANT_MOVE_MESSAGE: "Can't move message" - CANT_SAVE_MESSAGE: "Can't save message" - CANT_SEND_MESSAGE: "Can't send message" - INVALID_RECIPIENTS: "Invalid recipients" - CANT_SAVE_FILTERS: "Can't save filters" - CANT_GET_FILTERS: "Can't get filters" - FILTERS_ARE_NOT_CORRECT: "Filters are not correct" - CANT_CREATE_FOLDER: "Can't create folder" - CANT_RENAME_FOLDER: "Can't rename folder" - CANT_DELETE_FOLDER: "Can't delete folder" - CANT_DELETE_NON_EMPTY_FOLDER: "Can't delete non-empty directory" - CANT_SUBSCRIBE_FOLDER: "Can't subscribe folder" - CANT_UNSUBSCRIBE_FOLDER: "Can't unsubscribe folder" - CANT_SAVE_SETTINGS: "Can't save settings" - CANT_SAVE_PLUGIN_SETTINGS: "Can't save settings" - DOMAIN_ALREADY_EXISTS: "Domain already exists" - CANT_INSTALL_PACKAGE: "Failed to install package" - CANT_DELETE_PACKAGE: "Failed to remove package" - INVALID_PLUGIN_PACKAGE: "Invalid plugin package" - UNSUPPORTED_PLUGIN_PACKAGE: "Unsupported plugin package" - LICENSING_SERVER_IS_UNAVAILABLE: "Subscription server is unvailable" - LICENSING_DOMAIN_EXPIRED: "Subscription for this domain has expired." - LICENSING_DOMAIN_BANNED: "Subscription for this domain is banned." - DEMO_SEND_MESSAGE_ERROR: "For security purposes, this account is not allowed to send messages to external e-mail addresses!" - DEMO_ACCOUNT_ERROR: "For security purposes, this account is not allowed for this action!" - ACCOUNT_ALREADY_EXISTS: "Account already exists" - ACCOUNT_DOES_NOT_EXIST: "Account doesn't exist" - MAIL_SERVER_ERROR: "An error has occured while accessing mail server" - INVALID_INPUT_ARGUMENT: "Invalid input argument" - UNKNOWN_ERROR: "Unknown error" - STATIC: - BACK_LINK: "Reload" - DOMAIN_LIST_DESC: "List of domains webmail is allowed to access." - PHP_EXSTENSIONS_ERROR_DESC: "Required PHP extension are not available in your PHP configuration!" - PHP_VERSION_ERROR_DESC: "Your PHP version (%VERSION%) is lower than the minimal required 5.3.0!" - NO_SCRIPT_TITLE: "JavaScript is required for this application." + DOMAIN_NOT_ALLOWED: "Domain is not allowed" + ACCOUNT_NOT_ALLOWED: "Account is not allowed" + ACCOUNT_TWO_FACTOR_AUTH_REQUIRED: "Two factor verification required" + ACCOUNT_TWO_FACTOR_AUTH_ERROR: "Two factor verification error" + COULD_NOT_SAVE_NEW_PASSWORD: "Could not save new password" + CURRENT_PASSWORD_INCORRECT: "Current password incorrect" + NEW_PASSWORD_SHORT: "Password is too short" + NEW_PASSWORD_WEAK: "Password is too easy" + NEW_PASSWORD_FORBIDDENT: "Password contains forbidden characters" + CONTACTS_SYNC_ERROR: "Contacts synchronization error" + CANT_GET_MESSAGE_LIST: "Can't get message list" + CANT_GET_MESSAGE: "Can't get message" + CANT_DELETE_MESSAGE: "Can't delete message" + CANT_MOVE_MESSAGE: "Can't move message" + CANT_SAVE_MESSAGE: "Can't save message" + CANT_SEND_MESSAGE: "Can't send message" + INVALID_RECIPIENTS: "Invalid recipients" + CANT_SAVE_FILTERS: "Can't save filters" + CANT_GET_FILTERS: "Can't get filters" + FILTERS_ARE_NOT_CORRECT: "Filters are not correct" + CANT_CREATE_FOLDER: "Can't create folder" + CANT_RENAME_FOLDER: "Can't rename folder" + CANT_DELETE_FOLDER: "Can't delete folder" + CANT_DELETE_NON_EMPTY_FOLDER: "Can't delete non-empty directory" + CANT_SUBSCRIBE_FOLDER: "Can't subscribe folder" + CANT_UNSUBSCRIBE_FOLDER: "Can't unsubscribe folder" + CANT_SAVE_SETTINGS: "Can't save settings" + CANT_SAVE_PLUGIN_SETTINGS: "Can't save settings" + DOMAIN_ALREADY_EXISTS: "Domain already exists" + CANT_INSTALL_PACKAGE: "Failed to install package" + CANT_DELETE_PACKAGE: "Failed to remove package" + INVALID_PLUGIN_PACKAGE: "Invalid plugin package" + UNSUPPORTED_PLUGIN_PACKAGE: "Unsupported plugin package" + LICENSING_SERVER_IS_UNAVAILABLE: "Subscription server is unvailable" + LICENSING_DOMAIN_EXPIRED: "Subscription for this domain has expired." + LICENSING_DOMAIN_BANNED: "Subscription for this domain is banned." + DEMO_SEND_MESSAGE_ERROR: "For security purposes, this account is not allowed to send messages to external e-mail addresses!" + DEMO_ACCOUNT_ERROR: "For security purposes, this account is not allowed for this action!" + ACCOUNT_ALREADY_EXISTS: "Account already exists" + ACCOUNT_DOES_NOT_EXIST: "Account doesn't exist" + MAIL_SERVER_ERROR: "An error has occured while accessing mail server" + INVALID_INPUT_ARGUMENT: "Invalid input argument" + UNKNOWN_ERROR: "Unknown error" + STATIC: + BACK_LINK: "Reload" + DOMAIN_LIST_DESC: "List of domains webmail is allowed to access." + PHP_EXSTENSIONS_ERROR_DESC: "Required PHP extension are not available in your PHP configuration!" + PHP_VERSION_ERROR_DESC: "Your PHP version (%VERSION%) is lower than the minimal required 5.3.0!" + NO_SCRIPT_TITLE: "JavaScript is required for this application." NO_SCRIPT_DESC: | JavaScript support is not available in your browser. Please enable JavaScript support in your browser settings and retry. - NO_COOKIE_TITLE: "Cookies support is required for this application." + NO_COOKIE_TITLE: "Cookies support is required for this application." NO_COOKIE_DESC: | Cookies support is not available in your browser. Please enable Cookie support in your browser settings and retry. - BAD_BROWSER_TITLE: "Your browser is outdated." + BAD_BROWSER_TITLE: "Your browser is outdated." BAD_BROWSER_DESC: | To use all the features of the application, download and install one of these browsers: diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/ar_SA.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/ar_SA.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/webmail/ar_SA.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/webmail/ar_SA.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/bg_BG.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/bg_BG.yml similarity index 99% rename from rainloop/app/rainloop/v/1.12.0/app/localization/webmail/bg_BG.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/webmail/bg_BG.yml index 53bbc3df1355af3b1818d979b08bcc642f77c30d..90fd99ac42812bacebcdca08894cd6f59d704523 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/bg_BG.yml +++ b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/bg_BG.yml @@ -314,7 +314,7 @@ bg_BG: LABEL_CODE: "Код" BUTTON_TEST: "Тест" POPUPS_FILTER: - TITLE_CREATE_FILTER: "Въздай филтър?" + TITLE_CREATE_FILTER: "Създай филтър?" TITLE_EDIT_FILTER: "Обнови филтъра?" FILTER_NAME: "Име" LEGEND_CONDITIONS: "Условия" diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/cs_CZ.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/cs_CZ.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/webmail/cs_CZ.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/webmail/cs_CZ.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/da_DK.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/da_DK.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/webmail/da_DK.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/webmail/da_DK.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/de_DE.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/de_DE.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/webmail/de_DE.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/webmail/de_DE.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/el_GR.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/el_GR.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/webmail/el_GR.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/webmail/el_GR.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/en_GB.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/en_GB.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/webmail/en_GB.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/webmail/en_GB.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/en_US.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/en_US.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/webmail/en_US.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/webmail/en_US.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/es_ES.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/es_ES.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/webmail/es_ES.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/webmail/es_ES.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/et_EE.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/et_EE.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/webmail/et_EE.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/webmail/et_EE.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/fa_IR.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/fa_IR.yml similarity index 99% rename from rainloop/app/rainloop/v/1.12.0/app/localization/webmail/fa_IR.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/webmail/fa_IR.yml index 76c95e25da2b18d3ffb2252441e95fdc134df94b..63429dbebdbfe0188b407314ceeb26d17a82098e 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/fa_IR.yml +++ b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/fa_IR.yml @@ -145,11 +145,13 @@ fa_IR: PRINT_LABEL_ATTACHMENTS: "پیوست‌ها" MESSAGE_LOADING: "در حال بارگذاری" MESSAGE_VIEW_DESC: "پیام را در لیست جهت مشاهده انتخاب کنید" + MESSAGE_VIEW_MOVE_DESC: "بر روی نام شاخه در پنل سمت راست جهت انتخاب مقصد کلیک کنید" PGP_PASSWORD_INPUT_PLACEHOLDER: "گذرواژه" PGP_SIGNED_MESSAGE_DESC: "پیام توسط OpenPGP امضاء شد (برای بررسی کلیک کنید)" PGP_ENCRYPTED_MESSAGE_DESC: "پیام توسط OpenPGP رمزنگاری شد (برای خارج شدن از حالت رمز کلیک کنید)" LINK_DOWNLOAD_AS_ZIP: "دریافت با پسوند zip" LINK_SAVE_TO_OWNCLOUD: "ذخیره در OwnCloud" + LINK_SAVE_TO_CLOUD: "در فضای ابری ذخیره کن" LINK_SAVE_TO_DROPBOX: "ذخیره در Dropbox" READ_RECEIPT: SUBJECT: "برگرداندن گیرنده (نمایش داده شد) - %SUBJECT%" @@ -580,6 +582,7 @@ fa_IR: TITLE_PUBLIC: "عمومی" DELETING_ASK: "اطمینان دارید؟" GENERATE_ONLY_HTTPS: "تنها HTTPS" + LABEL_ALLOW_DRAFT_AUTOSAVE: "ذخیره خودکار پیش‌نویس" SHORTCUTS_HELP: LEGEND_SHORTCUTS_HELP: "راهنمای میانبر‌های کیبرد" TAB_MAILBOX: "صندوق پستی" diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/fi_FI.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/fi_FI.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/webmail/fi_FI.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/webmail/fi_FI.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/fr_FR.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/fr_FR.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/webmail/fr_FR.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/webmail/fr_FR.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/hu_HU.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/hu_HU.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/webmail/hu_HU.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/webmail/hu_HU.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/id_ID.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/id_ID.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/webmail/id_ID.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/webmail/id_ID.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/is_IS.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/is_IS.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/webmail/is_IS.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/webmail/is_IS.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/it_IT.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/it_IT.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/webmail/it_IT.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/webmail/it_IT.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/ja_JP.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/ja_JP.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/webmail/ja_JP.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/webmail/ja_JP.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/ko_KR.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/ko_KR.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/webmail/ko_KR.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/webmail/ko_KR.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/lt_LT.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/lt_LT.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/webmail/lt_LT.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/webmail/lt_LT.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/lv_LV.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/lv_LV.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/webmail/lv_LV.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/webmail/lv_LV.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/nb_NO.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/nb_NO.yml similarity index 99% rename from rainloop/app/rainloop/v/1.12.0/app/localization/webmail/nb_NO.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/webmail/nb_NO.yml index ea528954dcae9678a00dbb93bc72df79765745f7..ec62d4253706d6ddd01700869c26f8ad30f1843b 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/nb_NO.yml +++ b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/nb_NO.yml @@ -673,7 +673,7 @@ nb_NO: CANT_CREATE_FOLDER: "Klarte ikke å lage mappe" CANT_RENAME_FOLDER: "Klarte ikke å endre navn på mappe" CANT_DELETE_FOLDER: "Klarte ikke å slette mappe" - CANT_DELETE_NON_EMPTY_FOLDER: "Klarte ikke å slette mappe med innhold" + CANT_DELETE_NON_EMPTY_FOLDER: "Du må slette mappeinnholdet før du kan slette mappa" CANT_SUBSCRIBE_FOLDER: "Klarte ikke å abonnere på mappe" CANT_UNSUBSCRIBE_FOLDER: "Klarte ikke å avslutte abonnement" CANT_SAVE_SETTINGS: "Klarte ikke å lagre innstillinger" diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/nl_NL.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/nl_NL.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/webmail/nl_NL.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/webmail/nl_NL.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/pl_PL.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/pl_PL.yml similarity index 63% rename from rainloop/app/rainloop/v/1.12.0/app/localization/webmail/pl_PL.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/webmail/pl_PL.yml index 5fa1378ac4761ab8165f0e8279c16f6b348fe44b..0592e8efbd8099e7f5b110edc55abeed86249376 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/pl_PL.yml +++ b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/pl_PL.yml @@ -5,12 +5,12 @@ pl_PL: LABEL_PASSWORD: "Hasło" LABEL_SIGN_ME: "Zapamiętaj mnie" LABEL_VERIFICATION_CODE: "Kod weryfikujący" - LABEL_DONT_ASK_VERIFICATION_CODE: "Nie pytaj o kod przez 2 tygodnie" + LABEL_DONT_ASK_VERIFICATION_CODE: "Nie pytaj o kod przez kolejne 2 tygodnie" BUTTON_SIGN_IN: "Zaloguj" TITLE_SIGN_IN_GOOGLE: "Zaloguj się przez Google" TITLE_SIGN_IN_FACEBOOK: "Zaloguj się przez Facebook" TITLE_SIGN_IN_TWITTER: "Zaloguj się przez Twitter" - LABEL_FORGOT_PASSWORD: "Zapomniałem hasło" + LABEL_FORGOT_PASSWORD: "Zapomniałem(-am) hasło" LABEL_REGISTRATION: "Rejestracja" TOP_TOOLBAR: BUTTON_ADD_ACCOUNT: "Dodaj konto" @@ -23,16 +23,16 @@ pl_PL: SEARCH: MAIN_INPUT_PLACEHOLDER: "Szukaj" TITLE_ADV: "Wyszukiwanie zaawansowane" - LABEL_ADV_FROM: "Od:" - LABEL_ADV_TO: "Do:" - LABEL_ADV_SUBJECT: "Temat:" - LABEL_ADV_TEXT: "Tekst:" - LABEL_ADV_HAS_ATTACHMENT: "Załącznik" - LABEL_ADV_HAS_ATTACHMENTS: "Ma załączniki" + LABEL_ADV_FROM: "Od" + LABEL_ADV_TO: "Do" + LABEL_ADV_SUBJECT: "Temat" + LABEL_ADV_TEXT: "Tekst" + LABEL_ADV_HAS_ATTACHMENT: "Posiada załącznik" + LABEL_ADV_HAS_ATTACHMENTS: "Posiada załączniki" LABEL_ADV_FLAGGED: "Oznaczona" LABEL_ADV_UNSEEN: "Nieprzeczytana" - LABEL_ADV_DATE: "Data:" - LABEL_ADV_DATE_ALL: "wszystkie" + LABEL_ADV_DATE: "Data" + LABEL_ADV_DATE_ALL: "Wszystkie" LABEL_ADV_DATE_3_DAYS: "do 3 dni" LABEL_ADV_DATE_7_DAYS: "do tygodnia" LABEL_ADV_DATE_MONTH: "do miesiąca" @@ -47,7 +47,7 @@ pl_PL: LOADING: "Ładowanie..." GALLERY_PREV: "Poprzedni (strzałka w lewo)" GALLERY_NEXT: "Następny (strzałka w prawo)" - GALLERY_COUNTER: "%curr% z: %total%" + GALLERY_COUNTER: "%curr% z %total%" IMAGE_ERROR: "Nie można załadować obrazu." AJAX_ERROR: "Nie można załadować zawartości." FOLDER_LIST: @@ -56,22 +56,22 @@ pl_PL: BUTTON_NEW_MESSAGE: "Nowa wiadomość" INBOX_NAME: "Odebrane" SENT_NAME: "Wysłane" - DRAFTS_NAME: "Wersje robocze" - SPAM_NAME: "Wiadomości śmieci - SPAM" + DRAFTS_NAME: "Szkice" + SPAM_NAME: "Spam" TRASH_NAME: "Kosz" ARCHIVE_NAME: "Archiwum" QUOTA: - TITLE: "Wykorzystanie miejsca" + TITLE: "Wykorzystane miejsce" MESSAGE_LIST: - BUTTON_RELOAD: "Odśwież" - BUTTON_MOVE_TO: "Przenieś" + BUTTON_RELOAD: "Odśwież listę wiadomości" + BUTTON_MOVE_TO: "Przenieś do" BUTTON_DELETE: "Usuń" BUTTON_ARCHIVE: "Archiwizuj" BUTTON_SPAM: "Oznacz jako SPAM" BUTTON_NOT_SPAM: "Oznacz jako pożądane" BUTTON_EMPTY_FOLDER: "Usuń zawartość folderu" - BUTTON_MULTY_FORWARD: "Przekaż dalej" - BUTTON_DELETE_WITHOUT_MOVE: "Usuń (pernamentnie)" + BUTTON_MULTY_FORWARD: "Przekaż dalej jako załącznik(i)" + BUTTON_DELETE_WITHOUT_MOVE: "Usuń permanentnie" BUTTON_MORE: "Więcej" MENU_SET_SEEN: "Oznacz jako przeczytane" MENU_SET_ALL_SEEN: "Oznacz wszystkie jako przeczytane" @@ -85,18 +85,18 @@ pl_PL: MENU_SELECT_SEEN: "Przeczytane" MENU_SELECT_FLAGGED: "Oznaczone jako ważne" MENU_SELECT_UNFLAGGED: "Oznaczone jako nieważne" - EMPTY_LIST: "Pusta lista" - EMPTY_SEARCH_LIST: "Brak wiadomości spełniających kryteria wyszukiwania" - SEARCH_RESULT_FOR: "Wyniki wyszukiwania dla: \"%SEARCH%\"" + EMPTY_LIST: "Brak wiadomości." + EMPTY_SEARCH_LIST: "Brak wiadomości spełniających kryteria wyszukiwania." + SEARCH_RESULT_FOR: "Wyniki wyszukiwania dla \"%SEARCH%\"" BACK_TO_MESSAGE_LIST: "powrót do listy wiadomości" LIST_LOADING: "Ładowanie..." EMPTY_SUBJECT_TEXT: "(Brak tematu)" - PUT_MESSAGE_HERE: "Przeciągnij tutaj wiadomość, żeby zobaczyć ją na liście" - TODAY_AT: "dzisiaj: %TIME%" - YESTERDAY_AT: "wczoraj: %TIME%" + PUT_MESSAGE_HERE: "Przeciągnij wiadomość tutaj, żeby zobaczyć ją na liście" + TODAY_AT: "dzisiaj o %TIME%" + YESTERDAY_AT: "wczoraj o %TIME%" SEARCH_PLACEHOLDER: "Szukaj" NEW_MESSAGE_NOTIFICATION: "Masz: %COUNT% now(-ą,-e,-ych) wiadomości!" - QUOTA_SIZE: "Wykorzystano: %SIZE% (%PROC%%) z: %LIMIT%" + QUOTA_SIZE: "Wykorzystano %SIZE% (%PROC%%) z %LIMIT%" MESSAGE: BUTTON_EDIT: "Edytuj" BUTTON_BACK: "Wstecz" @@ -106,22 +106,22 @@ pl_PL: BUTTON_ARCHIVE: "Archiwizuj" BUTTON_SPAM: "Oznacz jako niechcianą" BUTTON_NOT_SPAM: "Oznacz jako pożądaną" - BUTTON_MOVE_TO: "Przenieś" + BUTTON_MOVE_TO: "Przenieś do" BUTTON_MORE: "Więcej" BUTTON_REPLY: "Odpowiedz" BUTTON_REPLY_ALL: "Odpowiedz wszystkim" BUTTON_FORWARD: "Przekaż dalej" - BUTTON_FORWARD_AS_ATTACHMENT: "Przekaż jako załącznik" + BUTTON_FORWARD_AS_ATTACHMENT: "Przekaż dalej jako załącznik" BUTTON_EDIT_AS_NEW: "Zredaguj jako nową wiadomość" - BUTTON_SHOW_IMAGES: "Wyświetl obrazy" - BUTTON_NOTIFY_READ_RECEIPT: "Nadawca prosi o potwierdzenie odczytania tej wiadomości" + BUTTON_SHOW_IMAGES: "Wyświetl zewnętrzne obrazy" + BUTTON_NOTIFY_READ_RECEIPT: "Nadawca prosi o potwierdzenie odczytania tej wiadomości." BUTTON_IN_NEW_WINDOW: "Wyświetl w osobnym oknie" BUTTON_THREAD_LIST: "Lista wątków" BUTTON_THREAD_PREV: "Poprzedni" BUTTON_THREAD_NEXT: "Następny" BUTTON_THREAD_MORE: "Więcej wiadomości" MENU_HEADERS: "Pokaż nagłówki wiadomości" - MENU_VIEW_ORIGINAL: "Pokaż zródło" + MENU_VIEW_ORIGINAL: "Pokaż źródło" MENU_DOWNLOAD_ORIGINAL: "Pobierz jako plik eml" MENU_FILTER_SIMILAR: "Filtruj podobne wiadomości" MENU_PRINT: "Drukuj" @@ -129,32 +129,34 @@ pl_PL: LABEL_SUBJECT: "Temat" LABEL_DATE: "Data" LABEL_FROM: "Od" - LABEL_FROM_SHORT: "Od" + LABEL_FROM_SHORT: "od" LABEL_TO: "Do" - LABEL_TO_SHORT: "Do" + LABEL_TO_SHORT: "do" LABEL_CC: "Kopia" - LABEL_BCC: "Ukr. kopia" - LABEL_REPLY_TO: "Zwrot do" + LABEL_BCC: "Kopia ukryta" + LABEL_REPLY_TO: "Odpisz do" PRINT_LABEL_FROM: "Od" PRINT_LABEL_TO: "Do" PRINT_LABEL_CC: "Kopia" - PRINT_LABEL_BCC: "Ukr. kopia" - PRINT_LABEL_REPLY_TO: "Zwrot do" + PRINT_LABEL_BCC: "Kopia ukryta" + PRINT_LABEL_REPLY_TO: "Odpisz do" PRINT_LABEL_DATE: "Data" PRINT_LABEL_SUBJECT: "Temat" PRINT_LABEL_ATTACHMENTS: "Załączniki" MESSAGE_LOADING: "Ładowanie wiadomości..." - MESSAGE_VIEW_DESC: "Wybierz wiadomość do wyświetlenia" + MESSAGE_VIEW_DESC: "Wybierz wiadomość do wyświetlenia." + MESSAGE_VIEW_MOVE_DESC: "Kliknij nazwę folderu w lewym panelu, aby wybrać folder docelowy." PGP_PASSWORD_INPUT_PLACEHOLDER: "Hasło" - PGP_SIGNED_MESSAGE_DESC: "Podpisana" - PGP_ENCRYPTED_MESSAGE_DESC: "Zaszyfrowana" + PGP_SIGNED_MESSAGE_DESC: "Wiadomość podpisana OpenPGP (kliknij aby zweryfikować)" + PGP_ENCRYPTED_MESSAGE_DESC: "Wiadomość zaszyfrowana OpenPGP (kliknij aby odszyfrować)" LINK_DOWNLOAD_AS_ZIP: "Pobierz jako plik zip" LINK_SAVE_TO_OWNCLOUD: "Zapisz w ownCloud" + LINK_SAVE_TO_CLOUD: "Zapisz w chmurze" LINK_SAVE_TO_DROPBOX: "Zapisz w Dropbox-ie" READ_RECEIPT: - SUBJECT: "Potwierdzenie wyświetlenia wiadomości o tytule: %SUBJECT%" + SUBJECT: "Żądaj potwierdzenia wyświetlenia wiadomości - %SUBJECT%" BODY: | - Potwierdzenie wyświetlenia wiadomości wysłanej na adres: %READ-RECEIPT%. + Potwierdzenie wyświetlenia wiadomości wysłanej na adres %READ-RECEIPT%. Uwaga: Otrzymanie tego potwierdzenia jest dowodem na to, że wiadomość została wyświetlona na komputerze odbiorcy. Nie ma jednak żadnej gwarancji, że odbiorca faktycznie zapoznał się z jej treścią. @@ -175,15 +177,15 @@ pl_PL: EMPTY_SEARCH: "Nie znaleziono żadnych kontaktów" CLEAR_SEARCH: "Wyczyść wyniki" CONTACT_VIEW_DESC: "Wybierz kontakt do wyświetlenia" - LABEL_DISPLAY_NAME: "Nazwa:" - LABEL_EMAIL: "Adres e-mail:" - LABEL_PHONE: "Telefon:" - LABEL_WEB: "Strona WWW:" - LABEL_BIRTHDAY: "Urodziny:" + LABEL_DISPLAY_NAME: "Nazwa wyświetlana" + LABEL_EMAIL: "Adres e-mail" + LABEL_PHONE: "Telefon" + LABEL_WEB: "Strona WWW" + LABEL_BIRTHDAY: "Urodziny" LINK_ADD_EMAIL: "Dodaj adres e-mail" LINK_ADD_PHONE: "Dodaj nr telefonu" LINK_BIRTHDAY: "Urodziny" - PLACEHOLDER_ENTER_DISPLAY_NAME: "Nazwa" + PLACEHOLDER_ENTER_DISPLAY_NAME: "Nazwa wyświetlana" PLACEHOLDER_ENTER_LAST_NAME: "Nazwisko" PLACEHOLDER_ENTER_FIRST_NAME: "Imię" PLACEHOLDER_ENTER_NICK_NAME: "Pseudonim" @@ -194,7 +196,7 @@ pl_PL: ADD_MENU_NOTES: "Notatki" ADD_MENU_EMAIL: "Adres e-mail" ADD_MENU_PHONE: "Telefon" - ADD_MENU_URL: "Adres www" + ADD_MENU_URL: "Adres URL" ADD_MENU_ADDRESS: "Adres" ADD_MENU_BIRTHDAY: "Urodziny" ADD_MENU_TAGS: "Tagi" @@ -205,8 +207,8 @@ pl_PL: TITLE_FROM: "Od" TITLE_TO: "Do" TITLE_CC: "Kopia" - TITLE_BCC: "Ukr. kopia" - TITLE_REPLY_TO: "Zwrot do" + TITLE_BCC: "Kopia ukryta" + TITLE_REPLY_TO: "Odpisz do" TITLE_SUBJECT: "Temat" LINK_SHOW_INPUTS: "Pokaż wszystkie pola" BUTTON_SEND: "Wyślij" @@ -214,185 +216,185 @@ pl_PL: BUTTON_DELETE: "Usuń" BUTTON_CANCEL: "Anuluj" BUTTON_MINIMIZE: "Minimalizuj" - SAVED_TIME: "Zapisane: %TIME%" - SAVED_ERROR_ON_SEND: "Wiadomość została wysłana, ale nie została zapisana w folderze: Wysłane" + SAVED_TIME: "Zapisano o %TIME%" + SAVED_ERROR_ON_SEND: "Wiadomość została wysłana, ale nie została zapisana w folderze Wysłane" DISCARD_UNSAVED_DATA: "Odrzucić niezapisane dane?" ATTACH_FILES: "Dodaj załącznik" ATTACH_DROP_FILES_DESC: "Przeciągnij pliki tutaj" ATTACH_ITEM_CANCEL: "Anuluj" DROPBOX: "Dropbox" GOOGLE_DRIVE: "Dysk Google" - REPLY_MESSAGE_TITLE: "%DATETIME% - %EMAIL%" - FORWARD_MESSAGE_TOP_TITLE: "-------- Przekierowana wiadomość -------" - FORWARD_MESSAGE_TOP_FROM: "Od:" - FORWARD_MESSAGE_TOP_TO: "Do:" - FORWARD_MESSAGE_TOP_CC: "Kopia do:" - FORWARD_MESSAGE_TOP_SENT: "Wysłany:" - FORWARD_MESSAGE_TOP_SUBJECT: "Temat:" + REPLY_MESSAGE_TITLE: "%DATETIME%, %EMAIL%" + FORWARD_MESSAGE_TOP_TITLE: "-------- Wiadomość przekazana -------" + FORWARD_MESSAGE_TOP_FROM: "Od" + FORWARD_MESSAGE_TOP_TO: "Do" + FORWARD_MESSAGE_TOP_CC: "Kopia do" + FORWARD_MESSAGE_TOP_SENT: "Wysłano" + FORWARD_MESSAGE_TOP_SUBJECT: "Temat" EMPTY_TO_ERROR_DESC: "Wprowadź co najmniej jednego odbiorcę" - NO_ATTACHMENTS_HERE_DESC: "Brak załączników" - ATTACHMENTS_ERROR_DESC: "Ostrzeżenie! Nie wszystkie załaczniki zostały przesłane" - ATTACHMENTS_UPLOAD_ERROR_DESC: "Nie przesłano jeszcze wszystkich załączników" - BUTTON_REQUEST_READ_RECEIPT: "Potwierdzenie wyświetlenia wiadomości" + NO_ATTACHMENTS_HERE_DESC: "Brak załączników." + ATTACHMENTS_ERROR_DESC: "Ostrzeżenie! Nie wszystkie załączniki zostały przesłane na serwer." + ATTACHMENTS_UPLOAD_ERROR_DESC: "Jeszcze nie wszystkie załączniki zostały przesłane na serwer." + BUTTON_REQUEST_READ_RECEIPT: "Żądaj potwierdzenia wyświetlenia wiadomości" BUTTON_MARK_AS_IMPORTANT: "Oznacz jako ważną" BUTTON_OPEN_PGP: "OpenPGP (tylko wiadomości tekstowe)" - BUTTON_REQUEST_DSN: "Potwierdzenie dostarczenia wiadomości" + BUTTON_REQUEST_DSN: "Żądaj potwierdzenia dostarczenia wiadomości" POPUPS_WELCOME_PAGE: BUTTON_CLOSE: "Zamknij" POPUPS_ASK: BUTTON_YES: "Tak" BUTTON_NO: "Nie" DESC_WANT_CLOSE_THIS_WINDOW: "Na pewno zamknąć to okno?" - DESC_WANT_DELETE_MESSAGES: "Na pewno usunąć wiadomość(-i)?" + DESC_WANT_DELETE_MESSAGES: "Na pewno usunąć wiadomość(-ci)?" POPUPS_LANGUAGES: TITLE_LANGUAGES: "Wybierz język" POPUPS_ADD_ACCOUNT: - TITLE_ADD_ACCOUNT: "Dodawanie konta" + TITLE_ADD_ACCOUNT: "Czy dodać konto?" BUTTON_ADD_ACCOUNT: "Dodaj" - TITLE_UPDATE_ACCOUNT: "Aktualizacja konta" + TITLE_UPDATE_ACCOUNT: "Czy zaktualizować konto?" BUTTON_UPDATE_ACCOUNT: "Aktualizuj" POPUPS_IDENTITY: - TITLE_ADD_IDENTITY: "Dodawanie tożsamości" - TITLE_UPDATE_IDENTITY: "Aktualizacja tożsamości" + TITLE_ADD_IDENTITY: "Czy dodać tożsamość?" + TITLE_UPDATE_IDENTITY: "Czy zaktualizować tożsamość?" BUTTON_ADD_IDENTITY: "Dodaj" BUTTON_UPDATE_IDENTITY: "Aktualizuj" - LABEL_EMAIL: "Adres e-mail:" - LABEL_NAME: "Nazwa:" - LABEL_REPLY_TO: "Zwrot do" - LABEL_SIGNATURE: "Podpis:" + LABEL_EMAIL: "Adres e-mail" + LABEL_NAME: "Nazwa" + LABEL_REPLY_TO: "Odpisz do" + LABEL_SIGNATURE: "Podpis" LABEL_CC: "Kopia" - LABEL_BCC: "Ukr. kopia" - LABEL_SIGNATURE_INSERT_BEFORE: "Umieść podpis przed cytowanym tekstem" + LABEL_BCC: "Kopia ukryta" + LABEL_SIGNATURE_INSERT_BEFORE: "Umieszczaj ten podpis przed cytowanym tekstem w odpowiedziach" POPUPS_CREATE_FOLDER: - TITLE_CREATE_FOLDER: "Tworzenie folderu" - LABEL_NAME: "Nazwa folderu:" - LABEL_PARENT: "Folder nadrzędny:" + TITLE_CREATE_FOLDER: "Czy stworzyć folder?" + LABEL_NAME: "Nazwa folderu" + LABEL_PARENT: "Folder nadrzędny" BUTTON_CREATE: "Utwórz" BUTTON_CANCEL: "Anuluj" BUTTON_CLOSE: "Zamknij" TITLE_CREATING_PROCESS: "Tworzenie folderu" POPUPS_CLEAR_FOLDER: - TITLE_CLEAR_FOLDER: "Usuwanie wszystkich wiadomości z folderu" + TITLE_CLEAR_FOLDER: "Czy usunąć wszystkie wiadomości z folderu?" BUTTON_CLEAR: "Usuń wszystkie" BUTTON_CANCEL: "Anuluj" BUTTON_CLOSE: "Zamknij" DANGER_DESC_WARNING: "Ostrzeżenie!" - DANGER_DESC_HTML_1: "Wszystkie wiadomości w folderze: %FOLDER%, zostaną bezpowrotnie usunięte!" - DANGER_DESC_HTML_2: "Po rozpoczęciu, nie można przerwać lub anulować zadania." + DANGER_DESC_HTML_1: "Wszystkie wiadomości w folderze %FOLDER% zostaną bezpowrotnie usunięte!" + DANGER_DESC_HTML_2: "Po rozpoczęciu nie będzie możliwe przerwanie lub anulowanie zadania." TITLE_CLEARING_PROCESS: "Trwa usuwanie wszystkich wiadomości z folderu..." POPUPS_IMPORT_OPEN_PGP_KEY: TITLE_IMPORT_OPEN_PGP_KEY: "Importowanie klucza OpenPGP" BUTTON_IMPORT_OPEN_PGP_KEY: "Importuj" POPUPS_VIEW_OPEN_PGP_KEY: - TITLE_VIEW_OPEN_PGP_KEY: "Klucz OpenPGP" + TITLE_VIEW_OPEN_PGP_KEY: "Podgląd klucza OpenPGP" BUTTON_SELECT: "Zaznacz" BUTTON_CLOSE: "Zamknij" POPUPS_GENERATE_OPEN_PGP_KEYS: TITLE_GENERATE_OPEN_PGP_KEYS: "Generowanie klucza OpenPGP" - LABEL_EMAIL: "Adres e-mail:" - LABEL_NAME: "Imię i nazwisko:" - LABEL_PASSWORD: "Hasło:" - LABEL_KEY_BIT_LENGTH: "Długość klucza:" + LABEL_EMAIL: "Adres e-mail" + LABEL_NAME: "Nazwa" + LABEL_PASSWORD: "Hasło" + LABEL_KEY_BIT_LENGTH: "Długość klucza" BUTTON_GENERATE_OPEN_PGP_KEYS: "Generuj" POPUPS_COMPOSE_OPEN_PGP: - TITLE_COMPOSE_OPEN_PGP: "Podpisywanie/szyfrowanie" + TITLE_COMPOSE_OPEN_PGP: "Podpisywanie/szyfrowanie OpenPGP" LABEL_SIGN: "Podpisz" - LABEL_ENCRYPT: "Szyfruj" - LABEL_PASSWORD: "Hasło:" + LABEL_ENCRYPT: "Zaszyfruj" + LABEL_PASSWORD: "Hasło" BUTTON_SIGN: "Podpisz" - BUTTON_ENCRYPT: "Szyfruj" - BUTTON_SIGN_AND_ENCRYPT: "Podpisz i szyfruj" + BUTTON_ENCRYPT: "Zaszyfruj" + BUTTON_SIGN_AND_ENCRYPT: "Podpisz i zaszyfruj" POPUPS_MESSAGE_OPEN_PGP: - TITLE_MESSAGE_OPEN_PGP: "OpenPGP Decrypt" + TITLE_MESSAGE_OPEN_PGP: "Odszyfrowywanie OpenPGP" LABEL_KEY: "Klucz prywatny" LABEL_PASSWORD: "Password" - BUTTON_DECRYPT: "Decrypt" + BUTTON_DECRYPT: "Odszyfruj" POPUPS_TWO_FACTOR_TEST: - TITLE_TEST_CODE: "Test autoryzacji dwuskładnikowej" + TITLE_TEST_CODE: "Test autoryzacji 2-etapowej" LABEL_CODE: "Kod" BUTTON_TEST: "Testuj" POPUPS_FILTER: - TITLE_CREATE_FILTER: "Tworzenie filtra" - TITLE_EDIT_FILTER: "Aktualizacja filtra" + TITLE_CREATE_FILTER: "Czy stworzyć filtr?" + TITLE_EDIT_FILTER: "Czy zaktualizować filtr?" FILTER_NAME: "Nazwa" LEGEND_CONDITIONS: "Warunki" LEGEND_ACTIONS: "Działania" BUTTON_DONE: "Gotowe" BUTTON_ADD_CONDITION: "Dodaj warunek" SELECT_ACTION_NONE: "Brak" - SELECT_ACTION_MOVE_TO: "Przenieś" + SELECT_ACTION_MOVE_TO: "Przenieś do" SELECT_ACTION_FORWARD_TO: "Prześlij dalej" SELECT_ACTION_REJECT: "Odrzuć" SELECT_ACTION_VACATION_MESSAGE: "Wiadomość urlopowa" - SELECT_ACTION_DISCARD: "Usuń" - SELECT_FIELD_FROM: "Pole 'Od'" - SELECT_FIELD_RECIPIENTS: "Pole 'Kopia' lub 'Ukr. kopia'" - SELECT_FIELD_SUBJECT: "Pole 'Temat'" + SELECT_ACTION_DISCARD: "Porzuć" + SELECT_FIELD_FROM: "Od" + SELECT_FIELD_RECIPIENTS: "Adresaci (Do lub DW)" + SELECT_FIELD_SUBJECT: "Temat" SELECT_FIELD_HEADER: "Nagłówek" SELECT_FIELD_SIZE: "Rozmiar" SELECT_TYPE_CONTAINS: "zawiera" SELECT_TYPE_NOT_CONTAINS: "nie zawiera" - SELECT_TYPE_MATCHES: "zawiera (*,?)" - SELECT_TYPE_NOT_MATCHES: "nie zawiera (*,?)" - SELECT_TYPE_REGEXP: "Wyrażenie regularne:" - SELECT_TYPE_NOT_REGEXP: "Niepoprawne wyrażenie regularne:" - SELECT_TYPE_EQUAL_TO: "Zawiera:" - SELECT_TYPE_NOT_EQUAL_TO: "Nie zawiera:" + SELECT_TYPE_MATCHES: "zawiera (*, ?)" + SELECT_TYPE_NOT_MATCHES: "nie zawiera (*, ?)" + SELECT_TYPE_REGEXP: "Wyrażenie regularne" + SELECT_TYPE_NOT_REGEXP: "Niepoprawne wyrażenie regularne" + SELECT_TYPE_EQUAL_TO: "równy" + SELECT_TYPE_NOT_EQUAL_TO: "nierówny" SELECT_TYPE_OVER: "powyżej" SELECT_TYPE_UNDER: "poniżej" SELECT_MATCH_ANY: "Spełnia dowolny z warunków" SELECT_MATCH_ALL: "Spełnia wszystkie warunki" MARK_AS_READ_LABEL: "Oznacz jako przeczytane" - REPLY_INTERVAL_LABEL: "Liczba dni, po których wysłać odp." + REPLY_INTERVAL_LABEL: "Interwał odpowiedzi (dni)" KEEP_LABEL: "Zachowaj" STOP_LABEL: "Nie zatrzymuj przetwarzania reguł" EMAIL_LABEL: "Adres e-mail" VACATION_SUBJECT_LABEL: "Temat (opcjonalnie)" VACATION_MESSAGE_LABEL: "Wiadomość" VACATION_RECIPIENTS_LABEL: "Odbiorcy (rodzielone przecinkami)" - REJECT_MESSAGE_LABEL: "Powód odrzucenia" + REJECT_MESSAGE_LABEL: "Odrzuć wiadomość" ALL_INCOMING_MESSAGES_DESC: "Wszystkie przychodzące wiadomości" POPUPS_SYSTEM_FOLDERS: - TITLE_SYSTEM_FOLDERS: "Wybieranie folderów systemowych" - SELECT_CHOOSE_ONE: "wybierz" + TITLE_SYSTEM_FOLDERS: "Wybierz foldery systemowe" + SELECT_CHOOSE_ONE: "Wybierz" SELECT_UNUSE_NAME: "nie używaj" - LABEL_SENT: "Wysłane:" - LABEL_DRAFTS: "Wersje robocze:" - LABEL_SPAM: "Niechciane:" - LABEL_TRASH: "Kosz:" - LABEL_ARCHIVE: "Archiwum:" + LABEL_SENT: "Wysłane" + LABEL_DRAFTS: "Szkice" + LABEL_SPAM: "Spam" + LABEL_TRASH: "Kosz" + LABEL_ARCHIVE: "Archiwum" BUTTON_CANCEL: "Anuluj" BUTTON_CLOSE: "Zamknij" NOTIFICATION_SENT: | - Nie wybrano folderu: "Wysłane", do którego przenoszone są wysłane wiadomości. - Jeżeli wysyłane wiadomości nie mają być przechowywane, proszę zaznaczyć opcję: "Nie używaj". - NOTIFICATION_DRAFTS: "Nie wybrano folderu: \"Wersje robocze\", do którego są zapisywane wiadomości w trakcie ich tworzenia." + Nie wybrano folderu systemowego "Wysłane", do którego przenoszone są wysłane wiadomości. + Jeżeli wysyłane wiadomości nie mają być przechowywane, proszę zaznaczyć opcję "Nie używaj". + NOTIFICATION_DRAFTS: "Nie wybrano folderu \"Wersje robocze\", do którego są zapisywane wiadomości w trakcie ich tworzenia." NOTIFICATION_SPAM: | - Nie wybrano folderu: "Niechciane", do którego przenoszone są niepożadane wiadomości. - Jeżeli niechciane wiadomości mają być usuwane na stałe, proszę o zaznaczenie opcji: "Nie używaj". + Nie wybrano folderu "Spam", do którego przenoszone są niepożądane wiadomości. + Jeżeli niechciane wiadomości mają być usuwane na stałe, proszę o zaznaczenie opcji "Nie używaj". NOTIFICATION_TRASH: | - Nie wybrano folderu: "Kosz", do którego przenoszone są wszystkie usunięte wiadomości. - Jeżeli wiadomości mają być usuwane na stałe, proszę o zaznaczenie opcji: "Nie używaj". + Nie wybrano folderu "Kosz", do którego przenoszone są wszystkie usunięte wiadomości. + Jeżeli wiadomości mają być usuwane na stałe, proszę o zaznaczenie opcji "Nie używaj". NOTIFICATION_ARCHIVE: "Nie został wybrany folder \"Archiwum\", zostanie użyty systemowy folder archiwizacji wiadomości." POPUPS_TWO_FACTOR_CFG: - LEGEND_TWO_FACTOR_AUTH: "Dwuskładnikowa autoryzacja" - LABEL_ENABLE_TWO_FACTOR: "Włącz dwuskładnikową autoryzację" - LABEL_TWO_FACTOR_USER: "Użytkownik:" - LABEL_TWO_FACTOR_STATUS: "Status:" - LABEL_TWO_FACTOR_SECRET: "Tajna fraza:" - LABEL_TWO_FACTOR_BACKUP_CODES: "Kody zapasowe:" + LEGEND_TWO_FACTOR_AUTH: "Autoryzacja 2-etapowa (TOTP)" + LABEL_ENABLE_TWO_FACTOR: "Włącz autoryzację 2-etapową" + LABEL_TWO_FACTOR_USER: "Użytkownik" + LABEL_TWO_FACTOR_STATUS: "Status" + LABEL_TWO_FACTOR_SECRET: "Tajna fraza" + LABEL_TWO_FACTOR_BACKUP_CODES: "Kody zapasowe" BUTTON_CREATE: "Utwórz nową frazę" BUTTON_ACTIVATE: "Aktywuj" BUTTON_CLEAR: "Wyczyść" BUTTON_LOGOUT: "Wyloguj" BUTTON_DONE: "Zamknij" BUTTON_TEST: "Testuj" - LINK_TEST: "Test" + LINK_TEST: "test" BUTTON_SHOW_SECRET: "Pokaż frazę" BUTTON_HIDE_SECRET: "Ukryj frazę" - TWO_FACTOR_REQUIRE_DESC: "Twoje konto wymaga skonfigurowania dwuskładnikowej autoryzacji ." - TWO_FACTOR_SECRET_CONFIGURED_DESC: "Skonfigurowana" - TWO_FACTOR_SECRET_NOT_CONFIGURED_DESC: "Nie skonfigurowana" + TWO_FACTOR_REQUIRE_DESC: "Twoje konto wymaga skonfigurowania autoryzacji 2-etapowej." + TWO_FACTOR_SECRET_CONFIGURED_DESC: "Skonfigurowano" + TWO_FACTOR_SECRET_NOT_CONFIGURED_DESC: "Nie skonfigurowano" TWO_FACTOR_SECRET_DESC: >- Użyj tych informacji w usłudze Google Authenticator (lub innym kliencie TOTP), używając poniższego kodu QR lub wpisując kod ręcznie. @@ -403,17 +405,17 @@ pl_PL: TITLES: LOADING: "Ładowanie..." LOGIN: "Login" - MAILBOX: "Skrzynka Pocztowa" + MAILBOX: "Skrzynka Odbiorcza" SETTINGS: "Ustawienia" COMPOSE: "Utwórz" UPLOAD: ERROR_FILE_IS_TOO_BIG: "Plik jest za duży" - ERROR_FILE_PARTIALLY_UPLOADED: "Z powodu nieokreślonego błędu, plik nie został przesłany w całości" - ERROR_NO_FILE_UPLOADED: "Nie przesłano żadnego pliku" - ERROR_MISSING_TEMP_FOLDER: "Brakuje pliku tymczasowego" - ERROR_ON_SAVING_FILE: "Wystąpił nieoczekiwany błąd w trakcie przesyłania pliku" + ERROR_FILE_PARTIALLY_UPLOADED: "Z powodu nieokreślonego błędu plik nie został przesłany w całości" + ERROR_NO_FILE_UPLOADED: "Nie przesłano żadnego pliku na serwer" + ERROR_MISSING_TEMP_FOLDER: "Brak pliku tymczasowego" + ERROR_ON_SAVING_FILE: "Wystąpił nieoczekiwany błąd w trakcie przesyłania pliku na serwer" ERROR_FILE_TYPE: "Nieprawidłowy typ pliku" - ERROR_UNKNOWN: "Wystąpił nieznany błąd w trakcie przesyłania pliku" + ERROR_UNKNOWN: "Wystąpił nieznany błąd w trakcie przesyłania pliku na serwer" EDITOR: TEXT_SWITCHER_PLAINT_TEXT: "HTML <-> zwykły tekst" TEXT_SWITCHER_RICH_FORMATTING: "Wzbogacony format tekstowy" @@ -429,7 +431,7 @@ pl_PL: LABEL_FILTERS_NAME: "Filtry" LABEL_TEMPLATES_NAME: "Szablony" LABEL_SECURITY_NAME: "Bezpieczeństwo" - LABEL_SOCIAL_NAME: "Sieci społecznościowe" + LABEL_SOCIAL_NAME: "Media społecznościowe" LABEL_THEMES_NAME: "Motywy" LABEL_CHANGE_PASSWORD_NAME: "Hasło" LABEL_OPEN_PGP_NAME: "OpenPGP" @@ -439,39 +441,39 @@ pl_PL: BUTTON_SAVE: "Zapisz" BUTTON_ADD_FILTER: "Dodaj filtr" BUTTON_DELETE: "Usuń" - BUTTON_RAW_SCRIPT: "Utwórz własny skrypt użytkownika" + BUTTON_RAW_SCRIPT: "Użyj własnego skryptu użytkownika" SUBNAME_NONE: "Brak" SUBNAME_MOVE_TO: "Przenieś do \"%FOLDER%\"" SUBNAME_FORWARD_TO: "Przekaż do \"%EMAIL%\"" SUBNAME_REJECT: "Odrzuć" SUBNAME_VACATION_MESSAGE: "Wiadomość urlopowa" - SUBNAME_DISCARD: "Usuń" + SUBNAME_DISCARD: "Porzuć" CAPABILITY_LABEL: "Możliwości" LOADING_PROCESS: "Aktualizowanie listy filtrów" DELETING_ASK: "Czy jesteś pewny(a)?" CHACHES_NEED_TO_BE_SAVED_DESC: "Zmiany te muszą zostać zapisane na serwerze." SETTINGS_IDENTITY: LEGEND_IDENTITY: "Tożsamość" - LABEL_DISPLAY_NAME: "Imię i nazwisko" - LABEL_REPLY_TO: "Zwrot do" + LABEL_DISPLAY_NAME: "Nazwa" + LABEL_REPLY_TO: "Odpisz do" LABEL_SIGNATURE: "Podpis" - LABEL_ADD_SIGNATURE_TO_ALL: "Dadawaj podpis do wszystkich wiadomości" + LABEL_ADD_SIGNATURE_TO_ALL: "Dodawaj podpis do wszystkich wiadomości wychodzących" SETTINGS_SECURITY: LEGEND_SECURITY: "Bezpieczeństwo" - LABEL_CONFIGURE_TWO_FACTOR: "Konfiguracja dwuskładnikowej autoryzacji" - LABEL_AUTOLOGOUT: "Auto. wylogowanie:" + LABEL_CONFIGURE_TWO_FACTOR: "Konfiguracja autoryzacji 2-etapowej" + LABEL_AUTOLOGOUT: "Automatyczne wylogowanie" AUTOLOGIN_NEVER_OPTION_NAME: "Nidgy" - AUTOLOGIN_MINUTES_OPTION_NAME: "%MINUTES% minut" + AUTOLOGIN_MINUTES_OPTION_NAME: "%MINUTES% minut(a)" AUTOLOGIN_HOURS_OPTION_NAME: "%HOURS% godzina(-y)" SETTINGS_GENERAL: LEGEND_GENERAL: "Ogólne" - LABEL_LANGUAGE: "Język:" - LABEL_IDENTITY: "Tożsamość:" - LABEL_LAYOUT: "Układ:" + LABEL_LANGUAGE: "Język" + LABEL_IDENTITY: "Tożsamość" + LABEL_LAYOUT: "Układ" LABEL_LAYOUT_NO_SPLIT: "bez podziału" LABEL_LAYOUT_VERTICAL_SPLIT: "podział w pionie" LABEL_LAYOUT_HORIZONTAL_SPLIT: "podział w poziomie" - LABEL_EDITOR: "Format wiadomości:" + LABEL_EDITOR: "Format wiadomości" LABEL_EDITOR_HTML: "HTML" LABEL_EDITOR_PLAIN: "zwykły tekst" LABEL_EDITOR_HTML_FORCED: "HTML (wymuszony)" @@ -482,49 +484,49 @@ pl_PL: LABEL_ANIMATION_NONE: "brak" LABEL_VIEW_OPTIONS: "Opcje wyświetlania" LABEL_USE_PREVIEW_PANE: "Wyświetl okno podglądu" - LABEL_USE_CHECKBOXES_IN_LIST: "Wyświetl pola zaznaczenia w listach" + LABEL_USE_CHECKBOXES_IN_LIST: "Pokazuj pola zaznaczenia na listach" LABEL_USE_THREADS: "Używaj wątków" LABEL_REPLY_SAME_FOLDER: "Umieść odpowiedzi w folderach, z których pochodzą wiadomości" - LABEL_SHOW_IMAGES: "Zawsze wyświetlaj obrazy w wiadomościach" + LABEL_SHOW_IMAGES: "Zawsze wyświetlaj zewnętrzne obrazy w treści wiadomości" LABEL_SHOW_ANIMATION: "Użyj animacji" - LABEL_MESSAGE_PER_PAGE: "Wiad. na stronie:" + LABEL_MESSAGE_PER_PAGE: "Wiadomości na stronę" LABEL_NOTIFICATIONS: "Powiadomienia" LABEL_SOUND_NOTIFICATION: "Powiadomienia dźwiękowe" LABEL_CHROME_NOTIFICATION_DESC: "Wyświetlaj powiadomienia o nowych wiadomościach" LABEL_CHROME_NOTIFICATION_DESC_DENIED: "(Zablokowane przez przeglądarkę)" SETTINGS_CONTACTS: LEGEND_CONTACTS: "Kontakty" - LABEL_CONTACTS_AUTOSAVE: "Automatycznie dodaj nieznanych nadawców i odbiorców do książki adresowej" + LABEL_CONTACTS_AUTOSAVE: "Automatycznie dodawaj odbiorców do książki adresowej" LEGEND_CONTACTS_SYNC: "Zdalna synchronizacja (CardDAV)" LABEL_CONTACTS_SYNC_ENABLE: "Włącz zdalną synchronizację" - LABEL_CONTACTS_SYNC_SERVER: "Serwer:" - LABEL_CONTACTS_SYNC_AB_URL: "Adres URL:" - LABEL_CONTACTS_SYNC_USER: "Użytkownik:" - LABEL_CONTACTS_SYNC_PASSWORD: "Hasło:" + LABEL_CONTACTS_SYNC_SERVER: "Serwer" + LABEL_CONTACTS_SYNC_AB_URL: "URL książki adresowej" + LABEL_CONTACTS_SYNC_USER: "Użytkownik" + LABEL_CONTACTS_SYNC_PASSWORD: "Hasło" SETTINGS_THEMES: - LEGEND_THEMES: "Motyw" - LEGEND_THEMES_CUSTOM: "Własny motyw" + LEGEND_THEMES: "Motywy" + LEGEND_THEMES_CUSTOM: "Konfiguracja własnego motywu" LABEL_CUSTOM_TYPE: "Typ" LABEL_CUSTOM_TYPE_LIGHT: "Jasny" LABEL_CUSTOM_TYPE_DARK: "Ciemny" LABEL_CUSTOM_BACKGROUND_IMAGE: "Tło" - BUTTON_UPLOAD_BACKGROUND_IMAGE: "Prześlij własne tło (.JPG, .PNG)" - ERROR_FILE_IS_TOO_BIG: "Plik jest za duży (1MB+)" - ERROR_FILE_TYPE_ERROR: "Nieprawidłowy format pliku (obsługiwane są wyłącznie pliki .JPG i .PNG)" - ERROR_UNKNOWN: "Wystąpił nieznany błąd w trakcie przesyłania" + BUTTON_UPLOAD_BACKGROUND_IMAGE: "Prześlij własne tło (JPG, PNG)" + ERROR_FILE_IS_TOO_BIG: "Plik jest za duży" + ERROR_FILE_TYPE_ERROR: "Nieprawidłowy format pliku (obsługiwane są wyłącznie pliki JPG i PNG)" + ERROR_UNKNOWN: "Wystąpił nieznany błąd w trakcie przesyłania pliku na serwer" SETTINGS_SOCIAL: LEGEND_GOOGLE: "Konto Google" BUTTON_GOOGLE_CONNECT: "Połącz z Google" - BUTTON_GOOGLE_DISCONNECT: "Odłącz" - MAIN_GOOGLE_DESC: "Po zezwoleniu na logowanie przez: Google, możesz zalogować się na to konto używając przycisku: \"Google\" w panelu logowania." + BUTTON_GOOGLE_DISCONNECT: "Odłącz Google" + MAIN_GOOGLE_DESC: "Po zezwoleniu na logowanie przez Google, możesz zalogować się na to konto używając przycisku \"Google\" w panelu logowania." LEGEND_FACEBOOK: "Facebook" BUTTON_FACEBOOK_CONNECT: "Połącz z Facebook" - BUTTON_FACEBOOK_DISCONNECT: "Odłącz" - MAIN_FACEBOOK_DESC: "Po zezwoleniu na logowanie przez: Facebook, możesz zalogować się na to konto używając przycisku: \"Facebook\" w panelu logowania." + BUTTON_FACEBOOK_DISCONNECT: "Odłącz Facebook" + MAIN_FACEBOOK_DESC: "Po zezwoleniu na logowanie przez Facebook, możesz zalogować się na to konto używając przycisku \"Facebook\" w panelu logowania." LEGEND_TWITTER: "Twitter" BUTTON_TWITTER_CONNECT: "Połącz z Twitter" - BUTTON_TWITTER_DISCONNECT: "Odłącz" - MAIN_TWITTER_DESC: "Po zezwoleniu na logowanie przez: Twitter, możesz zalogować się na to konto używając przycisku: \"Twitter\" w panelu logowania." + BUTTON_TWITTER_DISCONNECT: "Odłącz Twitter" + MAIN_TWITTER_DESC: "Po zezwoleniu na logowanie przez Twitter, możesz zalogować się na to konto używając przycisku \"Twitter\" w panelu logowania." SETTINGS_FOLDERS: LEGEND_FOLDERS: "Lista folderów" BUTTON_CREATE: "Utwórz folder" @@ -556,21 +558,21 @@ pl_PL: LEGEND_IDENTITY: "Tożsamość" LEGEND_IDENTITIES: "Dodatkowe tożsamości" LABEL_DEFAULT: "Domyślna" - LABEL_DISPLAY_NAME: "Nazwa:" - LABEL_REPLY_TO: "Odpowiedź do:" - LABEL_SIGNATURE: "Podpis:" - LABEL_ADD_SIGNATURE_TO_ALL: "Dodaj podpis do wszystkich wysyłanych wiadomości" + LABEL_DISPLAY_NAME: "Nazwa" + LABEL_REPLY_TO: "Odpisz do" + LABEL_SIGNATURE: "Podpis" + LABEL_ADD_SIGNATURE_TO_ALL: "Dodaj podpis do wszystkich wiadomości wychodzących" BUTTON_ADD_IDENTITY: "Dodaj tożsamość" BUTTON_DELETE: "Usuń" LOADING_PROCESS: "Trwa aktualizowanie listy tożsamości" DELETING_ASK: "Czy na pewno chcesz usunąć?" SETTINGS_CHANGE_PASSWORD: LEGEND_CHANGE_PASSWORD: "Zmiana hasła" - LABEL_CURRENT_PASSWORD: "Aktualne hasło:" - LABEL_NEW_PASSWORD: "Nowe hasło:" - LABEL_REPEAT_PASSWORD: "Powtórz nowe hasło:" + LABEL_CURRENT_PASSWORD: "Aktualne hasło" + LABEL_NEW_PASSWORD: "Nowe hasło" + LABEL_REPEAT_PASSWORD: "Powtórz nowe hasło" BUTTON_UPDATE_PASSWORD: "Zmień hasło na nowe" - ERROR_PASSWORD_MISMATCH: "Wpisane hasła nie pasują do siebie, proszę spróbować ponownie" + ERROR_PASSWORD_MISMATCH: "Podane hasła nie pasują do siebie, spróbuj ponownie" SETTINGS_OPEN_PGP: LEGEND_OPEN_PGP: "OpenPGP" BUTTON_ADD_OPEN_PGP_KEY: "Importuj klucz OpenPGP" @@ -579,26 +581,27 @@ pl_PL: TITLE_PUBLIC: "Publiczny" DELETING_ASK: "Czy na pewno chcesz usunąć?" GENERATE_ONLY_HTTPS: "Tylko HTTPS" + LABEL_ALLOW_DRAFT_AUTOSAVE: "Automatycznie zapisuj szkic" SHORTCUTS_HELP: - LEGEND_SHORTCUTS_HELP: "Skróty klawiaturowe" - TAB_MAILBOX: "Skrzynka pocztowa" + LEGEND_SHORTCUTS_HELP: "Pomoc dotycząca skrótów klawiaturowych" + TAB_MAILBOX: "Skrzynka odbiorcza" TAB_MESSAGE_LIST: "Lista wiadomości" TAB_MESSAGE_VIEW: "Widok wiadomości" TAB_COMPOSE: "Tworzenie wiadomości" LABEL_OPEN_USER_DROPDOWN: "Otwórz podręczne menu użytkownika" LABEL_REPLY: "Odpowiedz" LABEL_REPLY_ALL: "Odpowiedz wszystkim" - LABEL_FORWARD: "Przekaż" - LABEL_FORWARD_MULTIPLY: "Przekaż (wielokrotnie)" + LABEL_FORWARD: "Przekaż dalej" + LABEL_FORWARD_MULTIPLY: "Przekaż dalej jako załącznik(i)" LABEL_HELP: "Pomoc" - LABEL_CHECK_ALL: "Sprawdź wszystkie wiadomości" + LABEL_CHECK_ALL: "Zaznacz wszystkie wiadomości" LABEL_ARCHIVE: "Archiwum" LABEL_DELETE: "Usuń" LABEL_OPEN_THREAD: "Otwórz wybrany wątek" LABEL_MOVE: "Przenieś" - LABEL_READ: "Oznacz zaznaczone wiadomości, jako przeczytane" - LABEL_UNREAD: "Oznacz zaznaczone wiadomości, jako nieprzeczytane" - LABEL_IMPORTANT: "Oznacz zaznaczone wiadomości, jako ważne" + LABEL_READ: "Oznacz zaznaczone wiadomości jako przeczytane" + LABEL_UNREAD: "Oznacz zaznaczone wiadomości jako nieprzeczytane" + LABEL_IMPORTANT: "Oznacz zaznaczone wiadomości jako ważne" LABEL_SEARCH: "Szukaj" LABEL_CANCEL_SEARCH: "Anuluj szukanie" LABEL_FULLSCREEN_ENTER: "Pełny ekran (aktywny podgląd wiadomości)" @@ -621,46 +624,46 @@ pl_PL: LABEL_CLOSE_COMPOSE: "Zamknij okno tworzenia wiadomości" PGP_NOTIFICATIONS: NO_PUBLIC_KEYS_FOUND: "Nie znaleziono klucza publicznego" - NO_PUBLIC_KEYS_FOUND_FOR: "Nie znaleziono klucza publicznego dla adresu: \"%EMAIL%\"" + NO_PUBLIC_KEYS_FOUND_FOR: "Nie znaleziono klucza publicznego dla adresu \"%EMAIL%\"" NO_PRIVATE_KEY_FOUND: "Nie znaleziono klucza prywatnego" - NO_PRIVATE_KEY_FOUND_FOR: "Nie znaleziono klucza prywatnego dla adresu: \"%EMAIL%\"" + NO_PRIVATE_KEY_FOUND_FOR: "Nie znaleziono klucza prywatnego dla adresu \"%EMAIL%\"" ADD_A_PUBLICK_KEY: "Dodaj klucz publiczny" SELECT_A_PRIVATE_KEY: "Wybierz klucz prywatny" - UNVERIFIRED_SIGNATURE: "Niezweryfikowana" - DECRYPTION_ERROR: "Błąd deszyfrowania OpenPGP" - GOOD_SIGNATURE: "Podpisana przez: %USER%" + UNVERIFIRED_SIGNATURE: "Podpis niezweryfikowany" + DECRYPTION_ERROR: "Błąd odszyfrowywania OpenPGP" + GOOD_SIGNATURE: "Poprawnie podpisana przez %USER%" PGP_ERROR: "Błąd OpenPGP: %ERROR%" - SPECIFY_FROM_EMAIL: "Proszę podać adres e-mail w polu: OD" - SPECIFY_AT_LEAST_ONE_RECIPIENT: "Proszę podać przynajmniej jednego odbiorcę" + SPECIFY_FROM_EMAIL: "Podaj adres e-mail w polu OD" + SPECIFY_AT_LEAST_ONE_RECIPIENT: "Podaj przynajmniej jednego odbiorcę" NOTIFICATIONS: INVALID_TOKEN: "Nieprawidłowy token" AUTH_ERROR: "Błąd autoryzacji" ACCESS_ERROR: "Błąd dostępu" CONNECTION_ERROR: "Błąd połączenia z serwerem" - CAPTCHA_ERROR: "Nieprawidłowy kod CAPTCHA" + CAPTCHA_ERROR: "Nieprawidłowy kod CAPTCHA." SOCIAL_FACEBOOK_LOGIN_ACCESS_DISABLE: > - To społecznościowe ID (Facebooku), nie jest powiązane z żadnym kontem pocztowym. - Zaloguj się używając danych swojego konta e-mail i skonfiguruj tę opcję w: - Ustawienia > Sieci społecznościowe. + Ten identyfikator społecznościowy (Facebook) nie jest powiązany z żadnym kontem + pocztowym. Zaloguj się używając danych swojego konta e-mail i skonfiguruj + tę opcję w: Ustawienia > Sieci społecznościowe. SOCIAL_TWITTER_LOGIN_ACCESS_DISABLE: > - To społecznościowe ID (Twitter), nie jest powiązane z żadnym kontem pocztowym. - Zaloguj się używając danych swojego konta e-mail i skonfiguruj tę opcję w: - Ustawienia > Sieci społecznościowe. + Ten identyfikator społecznościowy (Twitter) nie jest powiązany z żadnym kontem + pocztowym. Zaloguj się używając danych swojego konta e-mail i skonfiguruj + tę opcję w: Ustawienia > Sieci społecznościowe. SOCIAL_GOOGLE_LOGIN_ACCESS_DISABLE: > - To społecznościowe ID (Konto Google), nie jest powiązane z żadnym kontem pocztowym. - Zaloguj się używając danych swojego konta e-mail i skonfiguruj tę opcję w: - Ustawienia > Sieci społecznościowe. + Ten identyfikator społecznościowy (Konto Google) nie jest powiązany z żadnym + kontem pocztowym. Zaloguj się używając danych swojego konta e-mail i skonfiguruj + tę opcję w: Ustawienia > Sieci społecznościowe. DOMAIN_NOT_ALLOWED: "Domena niedozwolona" ACCOUNT_NOT_ALLOWED: "Konto nie jest dozwolone" - ACCOUNT_TWO_FACTOR_AUTH_REQUIRED: "Wymagana dwuskładnikowa autoryzacja" - ACCOUNT_TWO_FACTOR_AUTH_ERROR: "Błąd dwuskładnikowej autoryzacji" + ACCOUNT_TWO_FACTOR_AUTH_REQUIRED: "Wymagana autoryzacja dwuetapowa" + ACCOUNT_TWO_FACTOR_AUTH_ERROR: "Błąd autoryzacji dwuetapowej" COULD_NOT_SAVE_NEW_PASSWORD: "Nie można było zapisać nowego hasła" CURRENT_PASSWORD_INCORRECT: "Obecne hasło jest niepoprawne" NEW_PASSWORD_SHORT: "Hasło jest za krótkie" NEW_PASSWORD_WEAK: "Hasło jest zbyt łatwe" - NEW_PASSWORD_FORBIDDENT: "Hasło zawiera zakazane znaki" + NEW_PASSWORD_FORBIDDENT: "Hasło zawiera niedozwolone znaki" CONTACTS_SYNC_ERROR: "Błąd synchronizacji kontaktów" - CANT_GET_MESSAGE_LIST: "Nie jest możliwe pobranie listy wiadomości" + CANT_GET_MESSAGE_LIST: "Nie można pobrać listy wiadomości" CANT_GET_MESSAGE: "Nie można pobrać wiadomości" CANT_DELETE_MESSAGE: "Nie można usunąć wiadomości" CANT_MOVE_MESSAGE: "Nie można przenieść wiadomości" @@ -669,25 +672,25 @@ pl_PL: INVALID_RECIPIENTS: "Nieprawidłowy adres odbiorcy" CANT_SAVE_FILTERS: "Nie można zapisać filtrów" CANT_GET_FILTERS: "Nie można pobrać filtrów" - FILTERS_ARE_NOT_CORRECT: "Filtry sa nieprawidłowe" + FILTERS_ARE_NOT_CORRECT: "Filtry są nieprawidłowe" CANT_CREATE_FOLDER: "Nie można utworzyć folderu" CANT_RENAME_FOLDER: "Nie można zmienić nazwy folderu" CANT_DELETE_FOLDER: "Nie można usunąć folderu" - CANT_DELETE_NON_EMPTY_FOLDER: "Nie można usunąć folderu w którym znajdują się wiadomości" - CANT_SUBSCRIBE_FOLDER: "Nie można przypisać folderu" - CANT_UNSUBSCRIBE_FOLDER: "Nie można wypisać z folderu" - CANT_SAVE_SETTINGS: "Nie można zmienić ustawień" - CANT_SAVE_PLUGIN_SETTINGS: "Nie mozna zmienić ustawień wtyczki" + CANT_DELETE_NON_EMPTY_FOLDER: "Nie można usunąć folderu, w którym znajdują się wiadomości" + CANT_SUBSCRIBE_FOLDER: "Nie można zasubskrybować folderu" + CANT_UNSUBSCRIBE_FOLDER: "Nie można usunąć subskrypcji folderu" + CANT_SAVE_SETTINGS: "Nie można zapisać ustawień" + CANT_SAVE_PLUGIN_SETTINGS: "Nie można zapisać ustawień" DOMAIN_ALREADY_EXISTS: "Domena już istnieje" CANT_INSTALL_PACKAGE: "Nieudana instalacja pakietu" CANT_DELETE_PACKAGE: "Nieudane usunięcie pakietu" INVALID_PLUGIN_PACKAGE: "Nieprawidłowy pakiet rozszerzenia" UNSUPPORTED_PLUGIN_PACKAGE: "Nieobsługiwany pakiet rozszerzenia" LICENSING_SERVER_IS_UNAVAILABLE: "Serwer subskrypcji jest niedostępny" - LICENSING_DOMAIN_EXPIRED: "Subskrypcja dla tej domeny wygasła" - LICENSING_DOMAIN_BANNED: "Subskrypcja dla tej domeny została zablokowana" - DEMO_SEND_MESSAGE_ERROR: "Ze względów bezpieczeństwa, to konto testowe nie ma możliwości przesyłania, wiadomości na zewnętrzne adresy e-mail." - DEMO_ACCOUNT_ERROR: "Ze względów bezpieczeństwa, ta akcja jest niedozwolona na tym koncie!" + LICENSING_DOMAIN_EXPIRED: "Subskrypcja dla tej domeny wygasła." + LICENSING_DOMAIN_BANNED: "Subskrypcja dla tej domeny została zablokowana." + DEMO_SEND_MESSAGE_ERROR: "Ze względów bezpieczeństwa konto testowe nie ma możliwości przesyłania wiadomości na zewnętrzne adresy e-mail." + DEMO_ACCOUNT_ERROR: "Ze względów bezpieczeństwa ta akcja jest niedozwolona na tym koncie!" ACCOUNT_ALREADY_EXISTS: "Konto o takiej nazwie już istnieje" ACCOUNT_DOES_NOT_EXIST: "Konto nie istnieje" MAIL_SERVER_ERROR: "Wystąpił błąd w trakcie połączenia z serwerem poczty" @@ -695,18 +698,18 @@ pl_PL: UNKNOWN_ERROR: "Nieznany błąd" STATIC: BACK_LINK: "Odśwież" - DOMAIN_LIST_DESC: "Lista domen do których webmail ma dostęp" + DOMAIN_LIST_DESC: "Lista domen, do których webmail ma dostęp." PHP_EXSTENSIONS_ERROR_DESC: "Wymagane rozszerzenia PHP są niedostępne!" PHP_VERSION_ERROR_DESC: "Aktualnie zainstalowana wersja PHP: (%VERSION%), jest niższa niż minimalnie wymagana 5.3.0!" - NO_SCRIPT_TITLE: "Ta aplikacja wymaga JavaScript" + NO_SCRIPT_TITLE: "Ta aplikacja wymaga JavaScript." NO_SCRIPT_DESC: | - Twoja przeglądarka nie obsługuje JavaScript - Proszę o umożliwienie obsługi JavaScript w przeglądarce, oraz ponowne załadowanie tej strony. + Twoja przeglądarka nie obsługuje JavaScript. + Włącz obsługę JavaScript w przeglądarce i ponowne załaduj tę stronę. NO_COOKIE_TITLE: "Ta aplikacja wymaga plików Cookies" NO_COOKIE_DESC: | - Obsługa Cookies jest wyłączona w twojej przeglądarce - Proszę o umożliwienie obsługi plików Cookie w przeglądarce oraz ponowne uruchomienie tej strony. - BAD_BROWSER_TITLE: "Twoja przeglądarka jest przestarzała!" + Obsługa Cookies jest wyłączona w Twojej przeglądarce. + Włącz obsługę plików Cookie w przeglądarce i spróbuj ponowne. + BAD_BROWSER_TITLE: "Twoja przeglądarka jest przestarzała." BAD_BROWSER_DESC: | W celu wykorzystania wszystkich funkcji tej aplikacji, zaktualizuj aktualnie używaną lub pobierz i zainstaluj jedną z poniższych przeglądarek: diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/pt_BR.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/pt_BR.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/webmail/pt_BR.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/webmail/pt_BR.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/pt_PT.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/pt_PT.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/webmail/pt_PT.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/webmail/pt_PT.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/ro_RO.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/ro_RO.yml similarity index 99% rename from rainloop/app/rainloop/v/1.12.0/app/localization/webmail/ro_RO.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/webmail/ro_RO.yml index 7d216b6a9723dbc98b881fcf6a1aeda8450f0653..afb0ee8ff2c69b5eb87723455a9b2e4bc59d30a1 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/ro_RO.yml +++ b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/ro_RO.yml @@ -45,8 +45,8 @@ ro_RO: ZOOM: "Zoom in/out" CLOSE: "Închide (Esc)" LOADING: "Se îcarcă..." - GALLERY_PREV: "Precedentul (Стрелка ←)" - GALLERY_NEXT: "Următorul (Стрелка →)" + GALLERY_PREV: "Precedentul (săgeată stânga)" + GALLERY_NEXT: "Următorul (săgeată dreapta)" GALLERY_COUNTER: "%curr% din %total%" IMAGE_ERROR: "Imaginea nu a putut fi încărcată" AJAX_ERROR: "Conținutul nu a putut fi încărcat" diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/ru_RU.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/ru_RU.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/webmail/ru_RU.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/webmail/ru_RU.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/sk_SK.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/sk_SK.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/webmail/sk_SK.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/webmail/sk_SK.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/sl_SI.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/sl_SI.yml similarity index 99% rename from rainloop/app/rainloop/v/1.12.0/app/localization/webmail/sl_SI.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/webmail/sl_SI.yml index e92a7ff7d41701156b4da52676a837b9c5e9a0f4..c177681e3374a44795c09988d6f44c4cb21f1bc6 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/sl_SI.yml +++ b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/sl_SI.yml @@ -151,6 +151,7 @@ sl_SI: PGP_ENCRYPTED_MESSAGE_DESC: "Sporočilo, šifrirano z OpenPGP (kliknite za dešifriranje)" LINK_DOWNLOAD_AS_ZIP: "Prenesi kot .zip datoteko" LINK_SAVE_TO_OWNCLOUD: "Shrani na ownCloud" + LINK_SAVE_TO_CLOUD: "Shrani v oblak" LINK_SAVE_TO_DROPBOX: "Shrani na Dropbox" READ_RECEIPT: SUBJECT: "Povratno poročilo (prikazano) - %SUBJECT%" @@ -580,6 +581,7 @@ sl_SI: TITLE_PUBLIC: "Javni" DELETING_ASK: "Ste prepričani?" GENERATE_ONLY_HTTPS: "Samo HTTPS" + LABEL_ALLOW_DRAFT_AUTOSAVE: "Samodejno shrani osnutek" SHORTCUTS_HELP: LEGEND_SHORTCUTS_HELP: "Tipkovne bližnjice" TAB_MAILBOX: "Nabiralnik" diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/sv_SE.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/sv_SE.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/webmail/sv_SE.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/webmail/sv_SE.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/tr_TR.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/tr_TR.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/webmail/tr_TR.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/webmail/tr_TR.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/uk_UA.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/uk_UA.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/webmail/uk_UA.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/webmail/uk_UA.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/zh_CN.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/zh_CN.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/webmail/zh_CN.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/webmail/zh_CN.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/localization/webmail/zh_TW.yml b/rainloop/app/rainloop/v/1.12.1/app/localization/webmail/zh_TW.yml similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/localization/webmail/zh_TW.yml rename to rainloop/app/rainloop/v/1.12.1/app/localization/webmail/zh_TW.yml diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/RainLoop.asc b/rainloop/app/rainloop/v/1.12.1/app/resources/RainLoop.asc similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/RainLoop.asc rename to rainloop/app/rainloop/v/1.12.1/app/resources/RainLoop.asc diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/empty-contact.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/empty-contact.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/empty-contact.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/empty-contact.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/amazon.com.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/amazon.com.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/amazon.com.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/amazon.com.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/apple.com.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/apple.com.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/apple.com.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/apple.com.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/asana.com.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/asana.com.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/asana.com.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/asana.com.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/battle.net.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/battle.net.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/battle.net.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/battle.net.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/blizzard.com.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/blizzard.com.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/blizzard.com.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/blizzard.com.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/cnet.online.com.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/cnet.online.com.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/cnet.online.com.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/cnet.online.com.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/connect.asana.com.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/connect.asana.com.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/connect.asana.com.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/connect.asana.com.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/e.paypal.com.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/e.paypal.com.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/e.paypal.com.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/e.paypal.com.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/ea.com.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/ea.com.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/ea.com.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/ea.com.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/ebay.com.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/ebay.com.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/ebay.com.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/ebay.com.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/em.ea.com.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/em.ea.com.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/em.ea.com.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/em.ea.com.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/email.blizzard.com.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/email.blizzard.com.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/email.blizzard.com.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/email.blizzard.com.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/email.microsoft.com.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/email.microsoft.com.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/email.microsoft.com.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/email.microsoft.com.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/email.skype.com.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/email.skype.com.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/email.skype.com.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/email.skype.com.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/facebook.com.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/facebook.com.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/facebook.com.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/facebook.com.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/facebookmail.com.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/facebookmail.com.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/facebookmail.com.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/facebookmail.com.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/github.com.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/github.com.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/github.com.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/github.com.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/google.com.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/google.com.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/google.com.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/google.com.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/id.apple.com.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/id.apple.com.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/id.apple.com.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/id.apple.com.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/intl.paypal.com.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/intl.paypal.com.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/intl.paypal.com.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/intl.paypal.com.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/microsoft.com.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/microsoft.com.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/microsoft.com.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/microsoft.com.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/microsoftonline.com.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/microsoftonline.com.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/microsoftonline.com.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/microsoftonline.com.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/myspace.com.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/myspace.com.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/myspace.com.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/myspace.com.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/news.myspace.com.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/news.myspace.com.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/news.myspace.com.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/news.myspace.com.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/news.onlive.com.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/news.onlive.com.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/news.onlive.com.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/news.onlive.com.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/onlive.com.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/onlive.com.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/onlive.com.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/onlive.com.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/paypal.com.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/paypal.com.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/paypal.com.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/paypal.com.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/plus.google.com.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/plus.google.com.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/plus.google.com.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/plus.google.com.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/postmaster.twitter.com.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/postmaster.twitter.com.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/postmaster.twitter.com.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/postmaster.twitter.com.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/reply.ebay.com.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/reply.ebay.com.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/reply.ebay.com.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/reply.ebay.com.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/reply1.ebay.com.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/reply1.ebay.com.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/reply1.ebay.com.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/reply1.ebay.com.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/reply2.ebay.com.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/reply2.ebay.com.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/reply2.ebay.com.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/reply2.ebay.com.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/reply3.ebay.com.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/reply3.ebay.com.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/reply3.ebay.com.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/reply3.ebay.com.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/skype.com.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/skype.com.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/skype.com.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/skype.com.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/steampowered.com.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/steampowered.com.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/steampowered.com.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/steampowered.com.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/ted.com.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/ted.com.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/ted.com.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/ted.com.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/twitter.com.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/twitter.com.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/twitter.com.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/twitter.com.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/resources/images/services/youtube.com.png b/rainloop/app/rainloop/v/1.12.1/app/resources/images/services/youtube.com.png similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/resources/images/services/youtube.com.png rename to rainloop/app/rainloop/v/1.12.1/app/resources/images/services/youtube.com.png diff --git a/rainloop/app/rainloop/v/1.12.0/app/templates/BadBrowser.html b/rainloop/app/rainloop/v/1.12.1/app/templates/BadBrowser.html similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/templates/BadBrowser.html rename to rainloop/app/rainloop/v/1.12.1/app/templates/BadBrowser.html diff --git a/rainloop/app/rainloop/v/1.12.0/app/templates/Error.html b/rainloop/app/rainloop/v/1.12.1/app/templates/Error.html similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/templates/Error.html rename to rainloop/app/rainloop/v/1.12.1/app/templates/Error.html diff --git a/rainloop/app/rainloop/v/1.12.0/app/templates/Index.html b/rainloop/app/rainloop/v/1.12.1/app/templates/Index.html similarity index 97% rename from rainloop/app/rainloop/v/1.12.0/app/templates/Index.html rename to rainloop/app/rainloop/v/1.12.1/app/templates/Index.html index e13fe4797abba0b53f3e0e6c4804b315cebe3033..3be1b78edafa90ba2a9532afd8b8029fe666005e 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/templates/Index.html +++ b/rainloop/app/rainloop/v/1.12.1/app/templates/Index.html @@ -1,30 +1,30 @@ - - - - - - - - - - - - - {{BaseContentSecurityPolicy}} - - {{BaseAppFaviconPngLinkTag}} - {{BaseAppFaviconTouchLinkTag}} - - - - - -
-
- - - + + + + + + + + + + + + + {{BaseContentSecurityPolicy}} + + {{BaseAppFaviconPngLinkTag}} + {{BaseAppFaviconTouchLinkTag}} + + + + + +
+
+ + + diff --git a/rainloop/app/rainloop/v/1.12.0/app/templates/Social.html b/rainloop/app/rainloop/v/1.12.1/app/templates/Social.html similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/templates/Social.html rename to rainloop/app/rainloop/v/1.12.1/app/templates/Social.html diff --git a/rainloop/app/rainloop/v/1.12.0/app/templates/Themes/template.less b/rainloop/app/rainloop/v/1.12.1/app/templates/Themes/template.less similarity index 96% rename from rainloop/app/rainloop/v/1.12.0/app/templates/Themes/template.less rename to rainloop/app/rainloop/v/1.12.1/app/templates/Themes/template.less index b4ebb2ab4b48019e482063c51dcc9bb706395855..90b00d0857a5e7ac16f06c5dc891f7840f853ccf 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/templates/Themes/template.less +++ b/rainloop/app/rainloop/v/1.12.1/app/templates/Themes/template.less @@ -1,357 +1,357 @@ - -// mixins +++ -.thm-linear-gradient-mixin(@start, @end) when (iscolor(@start)) and (iscolor(@end)) { - background-color: mix(@start, @end, 60%) !important; - background-image: -moz-linear-gradient(top, @start, @end) !important; // FF 3.6+ - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(@start), to(@end)) !important; // Safari 4+, Chrome 2+ - background-image: -webkit-linear-gradient(top, @start, @end) !important; // Safari 5.1+, Chrome 10+ - background-image: -o-linear-gradient(top, @start, @end !important); // Opera 11.10 - background-image: linear-gradient(to bottom, @start, @end) !important; // Standard, IE10 - background-repeat: repeat-x !important; - filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb(@start),argb(@end))) !important; // IE9 and down -} - -.thm-border-radius(@radius) when (ispixel(@radius)) { - -webkit-border-radius: @radius !important; - -moz-border-radius: @radius !important; - border-radius: @radius !important; -} - -.thm-box-shadow(@shadow) { - -webkit-box-shadow: @shadow !important; - -moz-box-shadow: @shadow !important; - box-shadow: @shadow !important; -} -.thm-body-background-image(@value) when (isstring(@value)) { - background-image: url("@{base}@{value}") !important; -} -.thm-body-background-image(@value) when not (isstring(@value)) { - background-image: @value !important; -} -.thm-rgba-background-color(@simple, @rgba) when (@rgba = false) { - background-color: @simple !important; -} -.thm-rgba-background-color(@simple, @rgba) when not (@rgba = false) { - background-color: @simple !important; - background-color: @rgba !important; -} -// --- mixins - -.thm-body { - color: @main-color; - background-color: @main-background-color; - background-size: @main-background-size; - .thm-body-background-image(@main-background-image); -} - -.thm-loading { - color: @loading-color !important; - text-shadow: @loading-text-shadow !important; - - .e-spinner .e-bounce { - background-color: @loading-color !important; - } -} - -.thm-login-desc .desc { - color: @loading-color !important; - text-shadow: @loading-text-shadow !important; -} - -.thm-login { - border: @login-border !important; - .thm-rgba-background-color(@login-background-color, @login-rgba-background-color); - .thm-linear-gradient-mixin(@login-gradient-start, @login-gradient-end); - .thm-border-radius(@login-border-radius); - .thm-box-shadow(@login-box-shadow); - - &.submitting-pane.submitting { - &:before{ - background: @spinner-background; - .thm-border-radius(@login-border-radius); - } - &:after{ - border-top-color: @spinner-color; - } - } -} - -.thm-login-text { - color: @login-color !important; - - .legend, .e-checkbox-icon, .g-ui-link, .social-button, .language-button { - color: @login-color !important; - } -} - -.thm-powered, .thm-mobile-switcher { - color: @powered-color; - a { - color: @powered-color; - &:hover { - color: lighten(@powered-color, 20%); - } - } -} - -.thm-languages { - color: @languages-color; - .flag-name { - color: @languages-color; - border-color: @languages-color; - } -} - -.g-ui-menu { - color: @dropdown-menu-color !important; - background-color: @dropdown-menu-background-color !important; -} - -.g-ui-menu .e-item > .e-link { - color: @dropdown-menu-color !important; - background-color: @dropdown-menu-background-color !important; - - > i { - color: @dropdown-menu-color !important; - } -} - -.g-ui-menu .e-item.selected > .e-link { - background-color: @dropdown-menu-selected-background-color !important; -} - -.g-ui-menu .e-item > .e-link:hover, .g-ui-menu .e-item > .e-link:focus { - color: @dropdown-menu-hover-color !important; - background-color: @dropdown-menu-hover-background-color !important; - - > i { - color: @dropdown-menu-hover-color !important; - } -} - -.g-ui-menu .e-item.disabled > .e-link, .g-ui-menu .e-item.disabled > .e-link:hover { - color: @dropdown-menu-disabled-color !important; - background-color: @dropdown-menu-background-color !important; - - > i { - color: @dropdown-menu-disabled-color !important; - } -} - -.thm-message-list-top-toolbar, .thm-message-list-bottom-toolbar { - .thm-rgba-background-color(@message-list-toolbar-background-color, @message-list-toolbar-rgba-background-color); - .thm-linear-gradient-mixin(@message-list-toolbar-gradient-start, @message-list-toolbar-gradient-end); -} - -.thm-folders .e-link { - - color: @folders-disabled-color !important; - - &.selectable { - color: @folders-color !important; - } - - &.selectable:hover { - color: @folders-hover-color !important; - .thm-rgba-background-color(@folders-hover-background-color, @folders-hover-rgba-background-color); - } - - &.selectable.selected { - color: @folders-selected-color !important; - .thm-rgba-background-color(@folders-selected-background-color, @folders-selected-rgba-background-color); - } - - &.focused { - color: @folders-focused-color !important; - .thm-rgba-background-color(@folders-focused-background-color, @folders-focused-rgba-background-color); - } - - &.selectable.droppableHover { - color: @folders-drop-color !important; - .thm-rgba-background-color(@folders-drop-background-color, @folders-drop-rgba-background-color); - } -} - -.thm-settings-menu .e-item { - - .e-link { - color: @settings-menu-disabled-color !important; - } - - &.selectable .e-link { - color: @settings-menu-color !important; - } - - &.selectable:hover .e-link { - .thm-rgba-background-color(@settings-menu-hover-background-color, @settings-menu-hover-rgba-background-color); - color: @settings-menu-hover-color !important; - } - - &.selectable.selected .e-link { - .thm-rgba-background-color(@settings-menu-selected-background-color, @settings-menu-selected-rgba-background-color); - color: @settings-menu-selected-color !important; - } -} - -.thm-message-view-background-color { - .thm-rgba-background-color(@message-background-color, @message-rgba-background-color); -} - -#rl-app{ - display: block; -} - -html.no-css { - - margin: 0; - padding: 0; - font-family: Arial, Verdana, Geneva, sans-serif; - - body { - margin: 0; - padding: 0; - } - - #rl-loading, #rl-loading-error { - position: absolute; - font-size: 30px; - line-height: 130%; - top: 50%; - width: 100%; - height: 65px; - margin: 0; - margin-top: -60px; - background-color: transparent; - text-align: center; - color: #333; - } - - .progressjs-container { - display: none; - } - - .thm-body { - color: #333; - background-color: #aaa; - background-image: none; - } - - .thm-loading { - color: #333 !important; - text-shadow: none !important; - - .e-spinner .e-bounce { - display: none !important; - } - } - - .thm-login-desc .desc { - color: #333 !important; - text-shadow: none !important; - } -} - -// glass style -html.glass { - - @glass-color: #fff !important; - @glass-p-color: #aaa !important; - @glass-error-color: #f76260 !important; - @glass-m-color: rgba(255, 255, 255, .8) !important; - - .thm-login { - background: none !important; - background: rgba(0, 0, 0, .5) !important; - box-shadow: none !important; - - border: none !important; - border: 1px solid rgba(255, 255, 255, .2) !important; - - .controls { - .input-append .add-on i { - color: @glass-m-color; - text-shadow: none !important; - outline: none !important; - box-shadow: none !important; - } - - input { - border: 1px solid none !important; - background: none !important; - outline: none !important; - text-shadow: none !important; - box-shadow: none !important; - - color: @glass-color; - border-color: @glass-m-color; - - &::-webkit-input-placeholder { - color: @glass-color; - text-shadow: none !important; - } - &::-moz-placeholder { - color: @glass-color; - text-shadow: none !important; - } - &:-moz-placeholder { - color: @glass-color; - text-shadow: none !important; - } - &:-ms-input-placeholder { - color: @glass-color; - text-shadow: none !important; - } - &:input-placeholder { - color: @glass-color; - text-shadow: none !important; - } - &:placeholder { - color: @glass-color; - text-shadow: none !important; - } - - &:focus, &:hover { - border-color: @glass-color; - } - } - .btn { - border: 1px solid none !important; - background: none !important; - outline: none !important; - text-shadow: none !important; - box-shadow: none !important; - - color: @glass-color; - border-color: @glass-m-color; - - text-transform: uppercase; - font-size: 13px; - - &:hover, &:active{ - border-color: @glass-color; - } - } - - &.error { - .input-append .add-on i { - color: @glass-error-color; - } - - input { - color: @glass-error-color; - border-color: @glass-error-color; - } - } - } - } - - .thm-login-text { - color: @glass-m-color; - text-shadow: none !important; - - .legend, .e-checkbox-icon, .g-ui-link, .social-button, .language-button { - color: @glass-m-color; - text-shadow: none !important; - } - } -} + +// mixins +++ +.thm-linear-gradient-mixin(@start, @end) when (iscolor(@start)) and (iscolor(@end)) { + background-color: mix(@start, @end, 60%) !important; + background-image: -moz-linear-gradient(top, @start, @end) !important; // FF 3.6+ + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(@start), to(@end)) !important; // Safari 4+, Chrome 2+ + background-image: -webkit-linear-gradient(top, @start, @end) !important; // Safari 5.1+, Chrome 10+ + background-image: -o-linear-gradient(top, @start, @end !important); // Opera 11.10 + background-image: linear-gradient(to bottom, @start, @end) !important; // Standard, IE10 + background-repeat: repeat-x !important; + filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb(@start),argb(@end))) !important; // IE9 and down +} + +.thm-border-radius(@radius) when (ispixel(@radius)) { + -webkit-border-radius: @radius !important; + -moz-border-radius: @radius !important; + border-radius: @radius !important; +} + +.thm-box-shadow(@shadow) { + -webkit-box-shadow: @shadow !important; + -moz-box-shadow: @shadow !important; + box-shadow: @shadow !important; +} +.thm-body-background-image(@value) when (isstring(@value)) { + background-image: url("@{base}@{value}") !important; +} +.thm-body-background-image(@value) when not (isstring(@value)) { + background-image: @value !important; +} +.thm-rgba-background-color(@simple, @rgba) when (@rgba = false) { + background-color: @simple !important; +} +.thm-rgba-background-color(@simple, @rgba) when not (@rgba = false) { + background-color: @simple !important; + background-color: @rgba !important; +} +// --- mixins + +.thm-body { + color: @main-color; + background-color: @main-background-color; + background-size: @main-background-size; + .thm-body-background-image(@main-background-image); +} + +.thm-loading { + color: @loading-color !important; + text-shadow: @loading-text-shadow !important; + + .e-spinner .e-bounce { + background-color: @loading-color !important; + } +} + +.thm-login-desc .desc { + color: @loading-color !important; + text-shadow: @loading-text-shadow !important; +} + +.thm-login { + border: @login-border !important; + .thm-rgba-background-color(@login-background-color, @login-rgba-background-color); + .thm-linear-gradient-mixin(@login-gradient-start, @login-gradient-end); + .thm-border-radius(@login-border-radius); + .thm-box-shadow(@login-box-shadow); + + &.submitting-pane.submitting { + &:before{ + background: @spinner-background; + .thm-border-radius(@login-border-radius); + } + &:after{ + border-top-color: @spinner-color; + } + } +} + +.thm-login-text { + color: @login-color !important; + + .legend, .e-checkbox-icon, .g-ui-link, .social-button, .language-button { + color: @login-color !important; + } +} + +.thm-powered, .thm-mobile-switcher { + color: @powered-color; + a { + color: @powered-color; + &:hover { + color: lighten(@powered-color, 20%); + } + } +} + +.thm-languages { + color: @languages-color; + .flag-name { + color: @languages-color; + border-color: @languages-color; + } +} + +.g-ui-menu { + color: @dropdown-menu-color !important; + background-color: @dropdown-menu-background-color !important; +} + +.g-ui-menu .e-item > .e-link { + color: @dropdown-menu-color !important; + background-color: @dropdown-menu-background-color !important; + + > i { + color: @dropdown-menu-color !important; + } +} + +.g-ui-menu .e-item.selected > .e-link { + background-color: @dropdown-menu-selected-background-color !important; +} + +.g-ui-menu .e-item > .e-link:hover, .g-ui-menu .e-item > .e-link:focus { + color: @dropdown-menu-hover-color !important; + background-color: @dropdown-menu-hover-background-color !important; + + > i { + color: @dropdown-menu-hover-color !important; + } +} + +.g-ui-menu .e-item.disabled > .e-link, .g-ui-menu .e-item.disabled > .e-link:hover { + color: @dropdown-menu-disabled-color !important; + background-color: @dropdown-menu-background-color !important; + + > i { + color: @dropdown-menu-disabled-color !important; + } +} + +.thm-message-list-top-toolbar, .thm-message-list-bottom-toolbar { + .thm-rgba-background-color(@message-list-toolbar-background-color, @message-list-toolbar-rgba-background-color); + .thm-linear-gradient-mixin(@message-list-toolbar-gradient-start, @message-list-toolbar-gradient-end); +} + +.thm-folders .e-link { + + color: @folders-disabled-color !important; + + &.selectable { + color: @folders-color !important; + } + + &.selectable:hover { + color: @folders-hover-color !important; + .thm-rgba-background-color(@folders-hover-background-color, @folders-hover-rgba-background-color); + } + + &.selectable.selected { + color: @folders-selected-color !important; + .thm-rgba-background-color(@folders-selected-background-color, @folders-selected-rgba-background-color); + } + + &.focused { + color: @folders-focused-color !important; + .thm-rgba-background-color(@folders-focused-background-color, @folders-focused-rgba-background-color); + } + + &.selectable.droppableHover { + color: @folders-drop-color !important; + .thm-rgba-background-color(@folders-drop-background-color, @folders-drop-rgba-background-color); + } +} + +.thm-settings-menu .e-item { + + .e-link { + color: @settings-menu-disabled-color !important; + } + + &.selectable .e-link { + color: @settings-menu-color !important; + } + + &.selectable:hover .e-link { + .thm-rgba-background-color(@settings-menu-hover-background-color, @settings-menu-hover-rgba-background-color); + color: @settings-menu-hover-color !important; + } + + &.selectable.selected .e-link { + .thm-rgba-background-color(@settings-menu-selected-background-color, @settings-menu-selected-rgba-background-color); + color: @settings-menu-selected-color !important; + } +} + +.thm-message-view-background-color { + .thm-rgba-background-color(@message-background-color, @message-rgba-background-color); +} + +#rl-app{ + display: block; +} + +html.no-css { + + margin: 0; + padding: 0; + font-family: Arial, Verdana, Geneva, sans-serif; + + body { + margin: 0; + padding: 0; + } + + #rl-loading, #rl-loading-error { + position: absolute; + font-size: 30px; + line-height: 130%; + top: 50%; + width: 100%; + height: 65px; + margin: 0; + margin-top: -60px; + background-color: transparent; + text-align: center; + color: #333; + } + + .progressjs-container { + display: none; + } + + .thm-body { + color: #333; + background-color: #aaa; + background-image: none; + } + + .thm-loading { + color: #333 !important; + text-shadow: none !important; + + .e-spinner .e-bounce { + display: none !important; + } + } + + .thm-login-desc .desc { + color: #333 !important; + text-shadow: none !important; + } +} + +// glass style +html.glass { + + @glass-color: #fff !important; + @glass-p-color: #aaa !important; + @glass-error-color: #f76260 !important; + @glass-m-color: rgba(255, 255, 255, .8) !important; + + .thm-login { + background: none !important; + background: rgba(0, 0, 0, .5) !important; + box-shadow: none !important; + + border: none !important; + border: 1px solid rgba(255, 255, 255, .2) !important; + + .controls { + .input-append .add-on i { + color: @glass-m-color; + text-shadow: none !important; + outline: none !important; + box-shadow: none !important; + } + + input { + border: 1px solid none !important; + background: none !important; + outline: none !important; + text-shadow: none !important; + box-shadow: none !important; + + color: @glass-color; + border-color: @glass-m-color; + + &::-webkit-input-placeholder { + color: @glass-color; + text-shadow: none !important; + } + &::-moz-placeholder { + color: @glass-color; + text-shadow: none !important; + } + &:-moz-placeholder { + color: @glass-color; + text-shadow: none !important; + } + &:-ms-input-placeholder { + color: @glass-color; + text-shadow: none !important; + } + &:input-placeholder { + color: @glass-color; + text-shadow: none !important; + } + &:placeholder { + color: @glass-color; + text-shadow: none !important; + } + + &:focus, &:hover { + border-color: @glass-color; + } + } + .btn { + border: 1px solid none !important; + background: none !important; + outline: none !important; + text-shadow: none !important; + box-shadow: none !important; + + color: @glass-color; + border-color: @glass-m-color; + + text-transform: uppercase; + font-size: 13px; + + &:hover, &:active{ + border-color: @glass-color; + } + } + + &.error { + .input-append .add-on i { + color: @glass-error-color; + } + + input { + color: @glass-error-color; + border-color: @glass-error-color; + } + } + } + } + + .thm-login-text { + color: @glass-m-color; + text-shadow: none !important; + + .legend, .e-checkbox-icon, .g-ui-link, .social-button, .language-button { + color: @glass-m-color; + text-shadow: none !important; + } + } +} diff --git a/rainloop/app/rainloop/v/1.12.0/app/templates/Themes/values.less b/rainloop/app/rainloop/v/1.12.1/app/templates/Themes/values.less similarity index 100% rename from rainloop/app/rainloop/v/1.12.0/app/templates/Themes/values.less rename to rainloop/app/rainloop/v/1.12.1/app/templates/Themes/values.less diff --git a/rainloop/app/rainloop/v/1.12.0/app/templates/Views/Admin/AdminLogin.html b/rainloop/app/rainloop/v/1.12.1/app/templates/Views/Admin/AdminLogin.html similarity index 98% rename from rainloop/app/rainloop/v/1.12.0/app/templates/Views/Admin/AdminLogin.html rename to rainloop/app/rainloop/v/1.12.1/app/templates/Views/Admin/AdminLogin.html index db784c2a7278dd6d9082a4ab28ab9e8a219978e5..dc6c1176e617214a6b551dfc36afd36bd308d778 100644 --- a/rainloop/app/rainloop/v/1.12.0/app/templates/Views/Admin/AdminLogin.html +++ b/rainloop/app/rainloop/v/1.12.1/app/templates/Views/Admin/AdminLogin.html @@ -1,50 +1,50 @@ -